3

After I set the right bar navigation button with a custom view, the selector is never called when the button is pressed. Here is my code:

UIImageView *navView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"notification_alert.png"]];
navView.frame = CGRectMake(0, 0, 40, 40);

self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:navView];
[self.navigationItem.rightBarButtonItem setTarget:self];
[self.navigationItem.rightBarButtonItem setAction:@selector(BtnClick:)];

The button appears correctly but the selector is never called. Any help would be appreciated!

-(IBAction)BtnClick:(id)sender
{
    NSLog(@"nav button clicked");
}
gumbynr
  • 335
  • 3
  • 16

2 Answers2

2

As ndmeiri mentioned

the bar button item expects the specified custom view to handle any user interactions

And this is how you do it:

   UIImageView *navView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"notification_alert.png"]];
    navView.userInteractionEnabled = YES;

self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:navView];

UITapGestureRecognizer *navViewTapRecognizer = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(btnClick:)];
[navViewTapRecognizer setNumberOfTouchesRequired:1];

[navView addGestureRecognizer:navViewTapRecognizer];
navView.userInteractionEnabled = YES;

The action :

-(void)btnClick:(id)sender
{
    NSLog(@"nav button clicked");
}

But it's better to just set a customized UIButton as a UIBarButtonItem

And this is how you do it :

UIButton *myButton = [[UIButton alloc] init];
myButton.frame=CGRectMake(0,0,40,40);
[myButton setBackgroundImage:[UIImage imageNamed: @"notification_alert.png"] forState:UIControlStateNormal];
[myButton addTarget:self action:@selector(BtnClick:) forControlEvents:UIControlEventTouchUpInside];

self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc]initWithCustomView:myButton];

Also you can setup an image like this :

self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"notification_alert.png"]
                                                                         style:UIBarButtonItemStylePlain
                                                                        target:self
                                                                        action:@selector(btnClick:)];
Alaeddine
  • 6,104
  • 3
  • 28
  • 45
  • not sure why this was voted down as it worked as intended... I tried the customized approach but the image is too large so I need to resize before using the first method – gumbynr Jul 11 '15 at 01:05
  • @gumbynr maybe because I published the code without explanation, I was intended to edit the answer after pasting the code. Anyway I have updated the code with a better way. Check the second solution. If it works you may correct the vote for this answer – Alaeddine Jul 11 '15 at 01:12
0

From the documentation for init(customView:):

The bar button item created by this method does not call the action method of its target in response to user interactions. Instead, the bar button item expects the specified custom view to handle any user interactions and provide an appropriate response.

See the UIBarButtonItem Class Reference for more information.

A workaround is to use a UIButton with a custom background image as the custom view, instead of a UIImageView. Then, add a target and action to the button.

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(0, 0, 40, 40);
[button setBackgroundImage:[UIImage imageNamed:@"background.png"] forState:UIControlStateNormal];
[button addTarget:self action:@selector(BtnClick:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *barButtontem = [[UIBarButtonItem alloc] initWithCustomView:button];
ndmeiri
  • 4,979
  • 12
  • 37
  • 45