Delegate Being Sent To Wrong Class

2019-09-08 16:09发布

问题:

I subclassed my navigation bar, making the title view clickable. When clicked, it will present another view controller. I am creating a protocol in the navigation bar, that will tell the navigation controller that the title view has been clicked. Here is how my navigation bar is defined:

NavigationBar.h:

@protocol NavigationBarDelegate;

@interface NavigationBar : UINavigationBar
{
    id <NavigationBarDelegate> delegate;
    BOOL _titleClicked;
}

@property (nonatomic, assign) id <NavigationBarDelegate> delegate;

@end

@protocol NavigationBarDelegate
@optional
- (void)titleButtonClicked:(BOOL)titleClicked;
@end

The delegate implements one optional method. The .m file is as follows:

NavigationBar.m:

@implementation NavigationBar

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        _titleClicked = 0;
    }
    return self;
}

- (void)drawRect:(CGRect)rect
{
    self.tintColor = [UIColor colorWithRed:(111/255.f) green:(158/255.f) blue:(54/255.f) alpha:(255/255.f)];

    UIImage *image = [UIImage imageNamed:@"titlelogo.png"];

    UIButton *titleButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, image.size.width, image.size.height)];
    titleButton.backgroundColor = [UIColor colorWithPatternImage:image];
    [titleButton addTarget:self action:@selector(titleButton:) forControlEvents:UIControlEventTouchUpInside];

    //        self.navigationController.delegate = self;
    [self.topItem setTitleView:titleButton];

    [super drawRect:rect];
}

- (void)titleButton:(UIButton *)sender
{
    _titleClicked = !_titleClicked;
    [self.delegate titleButtonClicked:_titleClicked];
}

This creates a navbar with a logo and calls the titleButton method when the title button has been clicked. Everything is fine up till here and the navigation bar displays nicely.

In my RootViewController:

NavigationBar *navigationBar = [[NavigationBar alloc] initWithFrame:CGRectMake(0.0f, 0.0f, self.view.frame.size.width, 44.0f)];
navigationBar.delegate = self;
[self.navigationController setValue:navigationBar forKey:@"navigationBar"];

An implementation of titleButtonClicked is also there. When I click on the title view however, I get the following error: -[UINavigationController titleButtonClicked:]: unrecognized selector sent to instance

Why am I getting titleButtonClicked sent to UINavigationController? Is there something I need to do in my navigation controller? I am just using plain old UINavigationController. Do I need to subclass that too? If so, why?

EDIT:

Calling po self.delegate on line [self.delegate titleViewClicked:_titleClicked]; in NavigationBar.m yields the result below. How did the delegate change its type? How can I fix that?

(lldb) po self.delegate
(objc_object *) $1 = 0x07550170 <UINavigationController: 0x7550170>

回答1:

You have a clash/ambiguity between your delegate and UINavigationBar's delegate property. Rename your delegate to disambiguate them.



回答2:

As @idz said, the problem is with your:

@property (nonatomic, assign) delegete;

Don't you see that it's weird that you don't even have a:

@synthesize delegete;

That's because UINavigationBar already defines a delegate variable as idz said.

change your declaration to:

// use unsafe_unretained in ARC, not assign
@property (nonatomic, unsafe_unretained) myDelegete;

and of course

@synthesize myDelegate;