How to set target and action for UIBarButtonItem at runtime

Viewed 95007

Tried this but only works for UIButton:

[btn setTarget:self action:@selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside];
12 Answers

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

Set target and action of your UIBarButtonItem

Swift 5 & 4

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

@objc func action (sender:UIButton) {
    print("action")
}

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:)];
UIBarButtonItem *barListBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemAdd target:self action:@selector(getTruckStopListAction)];   
self.navigationItem.rightBarButtonItem = barListBtn;
[barListBtn release];

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)

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.

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.

Related