Archive for 18th July 2009

Setting up an Objective-C delegate for the iPhone SDK

Once Ben Gottlieb of Standalone helped me get past the problem of creating and displaying my main view controller class, I set out to figure out how to do an Objective-C delegate. Unfortunately, none of the examples or tutorials I could find on the internet had a simple, straightforward explanation of what I needed to do to get it working.

After much trial and error, and reading up on as many descriptions on delegates that I could find, I got it working. Here are the steps that I had to go through in my code to get it working:

In my view subclass header file, this line was added to the top:

@protocol KeyboardViewDelegate;

This line was added to the class definition in the subclass header file:

id <KeyboardViewDelegate> delegate;

This line was added to the property definitions in the subclass header file:

@property (nonatomic, assign) id delegate;

And this section was added to the bottom of the subclass header file:

@protocol KeyboardViewDelegate<NSObject>
- (void) keyPressHandler:(int)keyPress;
@end

In my view subclass implementation file, this synthesize was added near the top:

@synthesize delegate;

And this section was added to the method in the subclass view that is wired up (via Interface Builder) to be called when a button is pressed on the view:

if(delegate && [delegate respondsToSelector:@selector(keyPressHandler:)]) {
    [delegate keyPressHandler:key];
}

In the view controller header file, of course the view subclass header needs to be included:

#import "KeyboardView.h"

I had to add the delegate name as part of the interface definition in the view controller header, adding the delegate name in angle brackets, changing it to look like this:

@interface MainViewController : UIViewController <KeyboardViewDelegate> {

And at the bottom of the view controller header file, I added a definition for the method that matches up with the one from the keyboard view:

- (void) keyPressHandler:(int)keyPress;

In the view controller implementation file, again the view header subclass needs to be included:

#import "KeyboardView.h"

In the viewDidLoad method of the view controller, during the creation of the view subclass, I had to set the subclass delegate to be the view controller:

CGRect sizeRect = CGRectMake(0, 225, 320, 190);
KeyboardView *view = [[KeyboardView alloc] init];
view.view.frame = sizeRect;
[view setDelegate:self];  // this line is pretty important !!!
[self.view addSubview:view.view];

And at the bottom of the view controller implementation file, thie method defined above is added:

- (void) keyPressHandler:(int)keyPress;
{
    NSLog(@"keyPressHandler just fired");
    // do something here
}

And that is it! When running in the simulator, the method in the view controller is fired whenever the method in the view subclass is fired.

Oh, and by the way, I am using a UIPageControl on my view controller, and I found out that, for some reason, I had to go into the viewDidLoad method and add the following line:

pageControl.backgroundColor = [UIColor grayColor];

If I did not add this line, the page control would never be visible, even though it was working, as when I tapped on either side of it, the code associated with it fired correctly. The background color of the page control was set to gray in Interface Builder. Anyone have any ideas why that would be?