This material is based on Paul Hegarty’s Lecture 5 and 6 iPhone course. For full explanation go there – these are abbreviated notes.

Say we have a View (FaceView) which knows how to draw a happy face but the level of it’s happiness (or smile) is currently hardwired to be 0 (not very happy).

And we’d like some externtal delegate to be able to set it for us.

Because Views can’t talk directly to controllers in iOS one way to do this is using protocols and delegates.

The view defines a protocol, which the controller implements thereby acting as the datasource for the view. Here’s how you hook it up.

1. Define the protocol and property.

FaceView.h

#import <UIKit/UIKit.h> 

@class FaceView;

@protocol FaceViewDataSource
- (float)smileForFaceView:(FaceView *)sender;
@end

@interface FaceView : UIView
@property (nonatomic, weak) IBOutlet id  dataSource;
@end

NB: Remember to synthesize the datasource in your .m file.

FaceView.m

@implementation FaceView
@synthesize dataSource = _dataSource;

What this basically says is create a protocol called smileForFaceView which returns a float (our smiliness) and takes as an input ourselves as the sender.

And then make that a publicly consumable property that others can register themselves for.

2. Use the delegate in your implementation.

For us our delegate is going to be used when we draw the smile in our drawRect function. So we replace the hard coded smile with:

FaceView.m

    //float smile = 100;
    float smile = [self.dataSource smileForFaceView:self];

3. Set controller as delegate.

So now FaceView is hooked up to use it’s delegate. Now we need to set our controller up to act as the delegate. This means having our controller say that they implement our FaceView protocol.

We could put in in our header file but because it’s private to our controller we stick it in our private interface.

HappinessViewController.m

@interface HappinessViewController() <FaceViewDataSource>

4. Do the implementation.

HappinessViewController.m

- (float)smileForFaceView:(FaceView *)sender {
    // set smile
}

5. Set delegate to be the controller.

Good time to do this is in the setter for our view in our controller.

HappinessViewController.m

-(void) setFaceView:(FaceView *)faceView
{
    _faceView = faceView;
    self.faceView.dataSource = self;
}

Voila! Now our controller is hooked up and ready to serve our view as it’s datasource.

Test

Add a button called refresh that when pressed sets the happiness.

- (IBAction)refresh:(id)sender {
    self.happiness = 100;
}

Should now see smile instead of frown (default of 0).