UIBarButtonItem: target action not working?

I have a custom view inside a UIBarButtonItem specified by calling -initWithCustomView . The My Button element is displayed fine, but when I click it, it does not trigger an action on my target.

Here is my code:

 UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"someImage.png"]]; UIBarButtonItem *bbItem = [[UIBarButtonItem alloc] initWithCustomView:imageView]; self.navigationItem.leftBarButtonItem = bbItem; [imageView release]; [bbItem setTarget:self]; [bbItem setAction:@selector(deselectAll)]; 
+58
ios objective-c iphone cocoa-touch
May 09 '10 at 2:45
source share
11 answers

I do not think that the purpose and action of UIBarButtonItem applies to custom views. Try using UIButton instead of UIImageView and apply the target and action to the button.

Sample code in Swift:

 let button = UIButton(type: .Custom) if let image = UIImage(named:"icon-menu.png") { button.setImage(image, forState: .Normal) } button.frame = CGRectMake(0.0, 0.0, 30.0, 30.0) button.addTarget(self, action: #selector(MyClass.myMethod), forControlEvents: .TouchUpInside) let barButton = UIBarButtonItem(customView: button) navigationItem.leftBarButtonItem = barButton 
+98
May 9 '10 at 3:17
source share

Here is how I do it:

 UIButton* infoButton = [UIButton buttonWithType: UIButtonTypeInfoLight]; [infoButton addTarget:self action:@selector(displayAboutUs) forControlEvents:UIControlEventTouchDown]; UIBarButtonItem* itemAboutUs =[[UIBarButtonItem alloc]initWithCustomView:infoButton]; … 
+23
Apr 05 '11 at 11:18
source share

I had the same problem, but I did not want to use UIButton instead of a custom view for my UIBarButtonItem (for a reverse response).

Alternatively, you can add a UIGestureRecognizer to the user view before using it to initialize the UIBarButtonItem ; this seems to work in my project.

Here is how I can change the source code:

 UIImageView *SOCImageView = [[UIImageView alloc] initWithImage: [UIImage imageNamed:@"cancel_wide.png"]]; UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(deselectAll:)]; [SOCImageView addGestureRecognizer:tapGesture]; SOItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithCustomView:SOCImageView] autorelease]; [tapGesture release]; [SOCImageView release]; 
+21
Jun 21 '12 at 15:37
source share

This is how I implemented UIButton inside a UIBarButtonItem:

 UIButton *logoButton = [UIButton buttonWithType:UIButtonTypeCustom]; [logoButton setImage: [UIImage imageNamed:@"icon.png"] forState:UIControlStateNormal]; logoButton.frame = CGRectMake(0, 0, 30, 30); [logoButton addTarget:self action:@selector(showAbout:) forControlEvents:UIControlEventTouchUpInside]; UIBarButtonItem *barItem = [[UIBarButtonItem alloc] initWithCustomView:logoButton]; self.navigationItem.rightBarButtonItem = barItem; [barItem release]; 
+9
Jun 13 2018-12-12T00: 00Z
source share

I had a similar problem. And I initially followed the path suggested by @drawnonward, but then ran into difficulties when I tried to get my actions to be a popover controller on an iPad. Using the built-in UIButton as a custom view means that the UIButton is the event sender and the presentPopoverFromBarButtonItem popover controllers: the method crashes when it tries to send it messages that are only suitable for real UIBarButtonItems.

The solution I eventually found was to steal the image that I wanted to use (the info icon) from the UIButton dropdown, and build my UIBarButtonItem as follows:

 // Make the info button use the standard icon and hook it up to work UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeInfoLight]; UIBarButtonItem *barButton = [[[UIBarButtonItem alloc] initWithImage:infoButton.currentImage style:UIBarButtonItemStyleBordered target:self action:@selector(showInfo:)] autorelease]; 

Using this initializer, you get a panel button whose target and selector really works. It's also simpler than wrapping an image in a user view, but it's just icing.

+7
Jun 16 '11 at 10:24
source share

Jacob, everything looks good, but you may not have specified the correct selector.

You can check if your action is really announced

 - (void) deselectAll; 

but not

 - (void) deselectAll:(id)sender; 

If this is the last, you need to set the action to @selector(deselectAll:) . (note the comma according to the method declaration)

In addition, void may be an IBAction , but this does not apply to this problem.

+1
May 09 '10 at 2:53
source share

Is your user view receiving touch events or passing them to the parent view?

0
May 09 '10 at 2:57 a.m.
source share

To make things easier, I created a category in UIBarButtonItem that looks like this:

 @implementation UIBarButtonItem (CustomButtonView) - (void)setButtonImage:(UIImage *)image { UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom]; [button setBackgroundImage:image forState:UIControlStateNormal]; [button sizeToFit]; [button addTarget:self.target action:self.action forControlEvents:UIControlEventTouchUpInside]; self.customView = button; } - (UIImage *)buttonImage { return [(UIButton *)self.customView imageForState:UIControlStateNormal]; } @end 

In client code, simply use:

 myBarButtonItem.buttonImage = [UIImage imagedNamed:@"image_name"]; 

Made in this way, you can still connect your goals and actions to IB (clicking on the UI configuration in IB is a good thing, as you can).

0
Jun 08 2018-12-12T00:
source share

Swift 3. I had a similar problem when I had a custom view inside a panel button element. To make the crane work, I assigned a gesture to my gaze and set the action. A presentation should be an outlet for its appointment. By doing this, he worked with a custom view.

Setting gestures as a class variable

 @IBOutlet weak var incidentView: UIView! let incidentTap = UITapGestureRecognizer() 

In viewDidLoad

 incidentTap.addTarget(self, action: #selector(self.changeIncidentBarItem)) incidentView.addGestureRecognizer(incidentTap) 
0
Dec 02 '16 at 19:29
source share

If you do not want to agree with UIImage and have a custom look in your barbuttonitem, install a gesture recognizer for touching the customview barbuttonitem property

let tap = UITapGestureRecognizer(target: self, action: #selector(goProButtonPressed)) deviceStatusBarButtonItem.customView?.addGestureRecognizer(tap)

0
Dec 03 '16 at 19:27
source share

Swift 3 : Below is my complete implementation for button customization and event handling.

 override func viewDidLoad() { super.viewDidLoad() let button = UIButton.init(type: .custom) button.setTitle("Tester", for: .normal) button.setTitleColor(.darkGray, for: .normal) button.layer.borderWidth = 1 button.layer.cornerRadius = 5 button.layer.borderColor = UIColor.darkGray.cgColor button.addTarget(self, action: #selector(self.handleButton), for: .touchUpInside) self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: button) } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) if let button = self.navigationItem.rightBarButtonItem?.customView { button.frame = CGRect(x:0, y:0, width:80, height:34) } } func handleButton( sender : UIButton ) { // It would be nice is isEnabled worked... sender.alpha = sender.alpha == 1.0 ? 0.5 : 1.0 } 

Hope this helps

0
Feb 02 '17 at 19:11
source share



All Articles