开发者

Properly implementing a Delegate & Protocol

I created this test case as a simple example of my problem.

  • The AppDelegate initializes the TestViewController and adds it to the window
  • The TestViewController initializes the TestView and makes it the view
  • The TestView initializes the TestSubView and adds it as a subview

My goal is to allow TestSubView, through a delegate, access to TestViewController's methods & variables. In this example TestSubView accesses the methods through either a touchesBegan or touchesMoved.

Please Help. Thank you.

EDIT: Still doesn't work, though no more errors. What I did: Moved the protocol definition to a separate file and imported it, retain to assign, and removed the @protocol TestDelegate declaration in the beginning of the header.

I think my problem is that I don't assign the delegate in the TestViewController.m, if that's the problem how would I do that?

TestViewController.h

#import <UIKit/UIKit.h>

@interface TestViewController : UIViewController <TestDelegate> {

    int number;
}

-(void)assignNumber:(int)value;
-(void)displayNumber;

@property int number;

@end

Moved to protocol.h and imported where needed

@protocol TestDeleg开发者_JS百科ate

-(void)assignNumber:(int)value;
-(void)displayNumber;

@end

TestViewController.m

#import "TestViewController.h"
#import "TestView.h"

@implementation TestViewController

@synthesize number;

- (void)loadView {
    TestView *myView = [[TestView alloc] initWithFrame:CGRectMake(0,0,320,480)];
    self.view = myView;
    [myView release];
}

-(void)assignNumber:(int)value {
    NSLog(@"Number Assigned");
    number = value;
}

-(void)displayNumber {
    NSLog(@"%i",number);
}

TestSubView.h

#import <UIKit/UIKit.h>
#import "TestViewController.h"


@interface TestSubView : UIView {

    id<TestDelegate> delegate;
}

@property (nonatomic, retain) id<TestDelegate> delegate;

@end

TestSubView.m

#import "TestSubView.h"
#import "TestViewController.h"

@implementation TestSubView

@synthesize delegate;

- (id)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:frame])) {
        // Initialization code
        [self setBackgroundColor:[UIColor redColor]];
        [self setUserInteractionEnabled:YES];
    }
    return self;
}


- (void)dealloc {
    [super dealloc];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    [self.delegate assignNumber:5];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

    [self.delegate displayNumber];  
}


First and foremost, you're declaring a protocol and then assigning the same object as implementing that protocol. What you're probably looking for is to declare the TestDelegate protocol on your TestSubView instead. Additionally when setting up a property for a delegate, be sure to use the 'assign' keyword as opposed to 'retain'.

Finally all of this can be greatly simplified by using UIGestureRecognizer. You can set it up in your controller and add it to your testSubView. This way, when the view recognizes that the corresponding gesture occurred within it's bounds, a message will be sent to your controller allowing you to do what you need to do like assigning or displaying a number.


You're referring to TestView when your class is called TestSubView, unless you have 2 classes defined.

TestView *myView = [[TestView alloc] initWithFrame:CGRectMake(0,0,320,480)];

You're correct that you're not assigning the delegate yet.
You would do that on the next line:

myView.delegate = self;

To end up with this:

- (void)loadView {
    TestSubView *myView = [[TestSubView alloc] initWithFrame:CGRectMake(0,0,320,480)];
    myView.delegate = self; // Set Delegate Here
    self.view = myView;
    [myView release];
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜