70

Tried this but only works for UIButton:

[btn setTarget:self action:@selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside];
Haroldo Gondim
  • 7,725
  • 9
  • 43
  • 62
Sharief
  • 1,487
  • 2
  • 18
  • 26

12 Answers12

113

Just set the UIBarButtonItem's target and action properties directly.

Ole Begemann
  • 135,006
  • 31
  • 278
  • 256
  • 52
    N.B. This only works if the `UIBarButtonItem` doesn't use a custom view, like a `UIButton` – Shaggy Frog Oct 01 '10 at 08:10
  • 24
    For custom views, use: [button addTarget:self action:@selector(buttonPressed) forControlEvents:UIControlEventTouchUpInside]; – Jarrod Nov 30 '12 at 02:03
  • Can you please give an example of what those should be set to? The target says it takes an AnyObject? Should that be set to a UIGestureRecognizer? – Unome Feb 26 '15 at 01:04
  • assuming btn is a UIBarButtonItem, [btn setTarget:self]; [btn setAction:@selector(btnClicked:)] or DOT notation btn.target = self; btn.action = @selector(btnClicked:); Both should work as @Ole-Begemann is describing. – zmonteca Mar 05 '15 at 00:46
  • @zmonteca hey, does it still work (6 years later)? how can I set a target and action to a UITabBarItem today? –  Aug 02 '16 at 14:25
  • @wp42 Should still work. This was just used last year on my end. – zmonteca Aug 02 '16 at 18:03
  • 2
    Per the documentation this doesn't work on an instance that has been initialized with a custom view. "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 http://apple.co/2egXdmR for reference – matt.writes.code Oct 17 '16 at 18:46
  • This only works if the UIBarButtonItem doesn't use a custom view – YodagamaHeshan Jun 14 '20 at 11:02
  • Did you figure out what worked if you used a custom view? – Ximena Flores de la Tijera Oct 05 '21 at 15:19
  • For a custom view where you add a UIButton, button, to a UIBarButtonItem, barButtonItem: button.addTarget(self, action: #selector(yourFunction), for: .touchUpInside). In other words, add it to the button that you're adding to the barbuttonitem. – Victor Engel Jul 29 '22 at 19:53
28

UIBarButtonItem doesnt have the same addTarget method so you have to set them directly as follows

btn.target = self;
btn.action = @selector(barButtonCustomPressed:);

...

// can specify UIBarButtonItem instead of id for this case
-(IBAction)barButtonCustomPressed:(UIBarButtonItem*)btn 
{
    NSLog(@"button tapped %@", btn.title);
}
mihai
  • 4,184
  • 3
  • 26
  • 27
19

Set target and action of your UIBarButtonItem

Swift 5 & 4

button.target = self
button.action = #selector(action)

@objc func action (sender:UIButton) {
    print("action")
}
Haroldo Gondim
  • 7,725
  • 9
  • 43
  • 62
15

I ran into a similar problem... I assume you mean that if your UIButton is not part of your UITabBar to call btnClicked then it works appropriately. If this is the problem you are proposing then, check your btnClicked method and change it from:

-btnClicked:(id)sender

to

-(void) btnClicked:(id)sender

that, and declare btnClicked in the header file...

For what it's worth, this is how I setup a button in tabbarbuttonitem:

UIBarButtonItem *exampleButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"button.png"] style:UIBarButtonItemStylePlain target:self action:@selector(btnClicked:)];
J. Dave
  • 335
  • 1
  • 4
  • 10
  • additionally, you can take out the ":" making ...:@selector(btnClicked:)]; into ...:@selector(btnClicked)]; – J. Dave Mar 17 '10 at 01:04
9

If you need this enough times in your code, it's nice to go ahead and extend UIBarButtonItem which I've done below in Swift. :)

import UIKit

extension UIBarButtonItem {
    func addTargetForAction(target: AnyObject, action: Selector) {
        self.target = target
        self.action = action
    }
}

As an example, with self as a UIViewController, you'd simply call:

self.myBarButtonItem.addTargetForAction(self, action: #selector(buttonPressed(_:))
serenn
  • 1,828
  • 1
  • 15
  • 11
  • This is a bad name, it suggests that previous target/actions are preserved as is the case with UIButton – jbat100 Oct 21 '22 at 09:20
7
UIBarButtonItem *barListBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemAdd target:self action:@selector(getTruckStopListAction)];   
self.navigationItem.rightBarButtonItem = barListBtn;
[barListBtn release];
aturan23
  • 4,798
  • 4
  • 28
  • 52
sinh99
  • 3,909
  • 32
  • 32
2

For a custom UIBarButtonItem this works.

let button = UIButton(type: .custom)
button.setImage(image, for: .normal)
button.addTarget(self, action: #selector(yourFunction), for: .touchUpInside)
let barButtonItem = UIBarButtonItem(customView: button)

You set the target and action to the button that you are adding to your UIBarButtonItem.

Victor Engel
  • 2,037
  • 2
  • 25
  • 46
1

@wp42 It does work today.

A nifty way of doing this in objective-C is adding a category to UIBarButtonItem class:

.h file

#import <UIKit/UIKit.h>

@interface UIBarButtonItem (addons)

-(void)addTarget:(id)target andAction:(SEL)action;

@end

.m file

#import "UIBarButtonItem+addons.h"

@implementation UIBarButtonItem (addons)

-(void)addTarget:(id)target andAction:(SEL)action{
   [self setTarget:target];
   [self setAction:action];
}

@end

In practice:

[myBtn addTarget:self andAction:@selector(myFunction:)];
Itai Spector
  • 652
  • 11
  • 24
1

For custom views: use an UITapGestureRecognizer and set up isUserInteractionEnabled to true.

profileImageView.isUserInteractionEnabled = true
let tap = UITapGestureRecognizer(target: self, action: #selector(handleProfileImageTap))
profileImageView.addGestureRecognizer(tap)
navigationItem.leftBarButtonItem = UIBarButtonItem(customView: profileImageView)
aturan23
  • 4,798
  • 4
  • 28
  • 52
oskarko
  • 3,382
  • 1
  • 26
  • 26
0

If you are programmatically adding the UIBarButtonItem, the best way to set the target and action is to initialize the button with one of the following methods:

UIBarButtonItem *customButton = [[UIBarButtonItem alloc] initWithImage:<#(UIImage)#> style:<#(UIBarButtonItemStyle)#> target:<#(id)#> action:<#(SEL)#>

UIBarButtonItem *customButton = [UIBarButtonItem alloc] initWithTitle:<#(NSString *)#> style:<#(UIBarButtonItemStyle)#> target:<#(id)#> action:<#(SEL)#>

UIBarButtonItem *customButton = [UIBarButtonItem alloc] initWithImage:<#(UIImage *)#> landscapeImagePhone:<#(UIImage *)#> style:<#(UIBarButtonItemStyle)#> target:<#(id)#> action:<#(SEL)#>
Adam Cooper
  • 867
  • 1
  • 6
  • 23
0

Swift 5:

Extract to extensions:

extension UIBarButtonItem {

    static func nextBtn(target: AnyObject, action: Selector) -> UIBarButtonItem {
        let title = "Next"
        return button(title: title, target: target, action: action)
    }

    private static func button(title: String, target: AnyObject, action: Selector) -> UIBarButtonItem {
        return UIBarButtonItem(title: title, style: .done, target: target, action: action)
    }

}

Call in code:

navigationItem.rightBarButtonItem = .nextBtn(target: self, action: #selector(rightBarButtonAction))

Action:

@objc func rightBarButtonAction() {
    Swift.print("Button tapped!")
}

Pretty easy to add new buttons to this factory.

atereshkov
  • 4,311
  • 1
  • 38
  • 49
-5

You may want to try out the addTarget method.

David Carvalho
  • 549
  • 1
  • 5
  • 8
  • 3
    There is no addTarget method for UIBarButtonItem. – Mike Aug 30 '13 at 05:16
  • That methohd does not exist, check the docs please: https://developer.apple.com/library/IOs/documentation/UIKit/Reference/UIBarButtonItem_Class/Reference/Reference.html What you are thinking of is a UIButton – katzenhut Nov 25 '13 at 16:05