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?

14 Comments

  1. Dana Maher says:

    I think you’re forgetting to include the property definition for delegate, which would be:

    @property(assign) id delegate;

    Right? Still working through the tutorial, but I couldn’t successfully compile without defining the property for delegate.

    Otherwise, this is a great tutorial.

  2. BP says:

    Dana: Good catch, I forgot to put that line in the posting. I have edited the posting to include the line (in which I included nonatomic, not sure if that is needed or not), as well as some other minor edits. Thanks for checking it out. BP

  3. Dana Maher says:

    Thanks, this was exactly what I needed to make my fragmented understanding of delegates whole.

    One more possible omission; did you forget to include the implementation of the KeyBoardViewDelegate protocol within your ViewController class:

    @interface TutorialViewController : UIViewController {

    }

    I get “______ class does not implement the ______ protocol” compiler warnings and run-time crashes if I don’t include in the class definition.

    Thanks again.

  4. Dana Maher says:

    Whoops, the website thought I was trying to do html formatting and made some of my text disappear. That line of code should look like:

    @interface TutorialViewController : UIViewController *KeyBoardViewDelegate* {

    }

    Except that the KeyBoardViewDelegate implementation has angle brackets around it rather than asterisks.

  5. BP says:

    Dana: You are right again, I forgot the item. I have edited the posting again, thanks. BP

  6. Petar says:

    Thanks for this – has been a great help.

  7. Matthias says:

    Thanks a lot. This really did help because this is a simple straightforward explanation!

  8. Dragan says:

    Wooohhhhooooo!
    Great tutorial!!! Keep on the great work!

  9. Alex says:

    Super tutorial!
    Good work.

  10. Nefsu says:

    Great tutorial. Better than anything on the apple website or anywhere else I looked. Thanks a lot!

  11. Denis says:

    This helped me a lot!! I’ve been scratching my head at other online tutorial for the past couple days. This just cleared it right up!

    Thanks again!
    Denis.

  12. Pedro Anisio says:

    Tks a LOT!!

    Great step by step information,save me a lot of time!

  13. Hari says:

    This is best explanation.

  14. […] to send message back and forth between classes for years. (And in fact, I did a blog post on Setting up an Objective-C delegate for the iPhone SDK a few years back on this very subject.) Indeed, delegates are a critical part of the Objective-C […]

Leave a Reply