Uibarbuttonitem Selector Not Working

UIBarButtonItem selector not working

try with inside scope once

override func viewDidLoad() {
super.viewDidLoad()

let rightButton = UIBarButtonItem(title: "Right", style: .plain, target: self, action: #selector(self.onRightLeftClick(_ :)))
rightButton.tag = 1
let leftButton = UIBarButtonItem(title: "Left", style: .plain, target: self, action: #selector(self.onRightLeftClick(_ :)))
rightButton.tag = 2
self.navigationItem.rightBarButtonItem = rightButton
self.navigationItem.leftBarButtonItem = leftButton
}

handle the action as

func onRightLeftClick(_ sender: UIBarButtonItem){
if sender.tag == 1{
// rightButton action
}else{
// leftButton action
}
}

#selector function of UIBarButtonItem not firing when pressed

Maybe the rest of the instance haven't initialised at the time your code is executed. Have you tried doing this in viewDidLoad? If not, try doing that:

override func viewDidLoad() {
super.viewDidLoad()

configureYourBarButtonHere()
}

I remember seeing a lot of questions that highlight this issue, with this solution. Here are a couple ones I could find for now:

UIBarButtonItem selector not working

https://stackoverflow.com/a/49283627/9293498

#selector on UIBarButtonItem

No quotes.

#selector(Utils.menuClicked(_:))

func menuClicked should be in your view controller class. But if for some reason it isn't, you can do

class Utils {
static let instance = Utils()

let menuButton = UIBarButtonItem(image: UIImage(named: "menu"),
style: UIBarButtonItemStyle.Plain ,
target: Utils.instance, action: #selector(Utils.menuClicked(_:)))

@objc func menuClicked(sender: UIBarButtonItem) {
// do stuff
}
}

UIBarButtonItem not firing up selector action

The code you provided should be working so you need to provide more context (show more of your view controller class where this is implemented).

UIKit provides a set of standard UIBarButtonItems called system items. These happen to include an 'add' item, which is displayed as a plus-sign and used throughout iOS. Using this item solves question 2 and 3.

UIBarButtonItem has a convenience constructor for initialising a system item. See the working example below:

class ViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()

let addProdButton = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addProduct))
navigationItem.leftBarButtonItem = addProdButton
}

@objc func addProduct() {
print("addProduct() called")
}
}

Selector not working on my swift UIBarButtonItem

Your showSettings: selector isn't being called because you specified nil instead of self for the bar button item's target. Change the line to:

self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(named: "modify"), style: UIBarButtonItemStyle.Plain, target: self, action: Selector("showSettings:"))

This assume the showSettings: method is in the same class that contains this line of code.

Read the documentation for this initializer, specifically the info about the target parameter.

SWIFT - UIBarButtonItem is not calling action

The problem is that uploadButton is getting initialized too early, i.e. during the initialization of the view controller ifself. At that point, self is not yet ready for use.

There are a few ways to solve this.

  1. Initialize the button in viewDidLoad:
class MyViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()
let uploadButton = UIBarButtonItem(title: "UPLOAD", style: .plain, target: self, action: #selector(uploadHandler))
self.navigationItem.setRightBarButton(uploadButton, animated: false)
}
...
}

  1. If some other methods in your class need access to it, slightly modify the code above by creating an implicitly unwrapped stored property and setting it in viewDidLoad:
class MyViewController: UIViewController {

private var uploadButton: UIBarButtonItem!

override func viewDidLoad() {
super.viewDidLoad()
uploadButton = UIBarButtonItem(title: "UPLOAD", style: .plain, target: self, action: #selector(uploadHandler))
self.navigationItem.setRightBarButton(uploadButton, animated: false)
}
...
}

  1. Make the initialization of the button lazy, that way it will be initialized when it's first accessed, i.e. in viewDidLoad:
class MyViewController: UIViewController {

private lazy var uploadButton = UIBarButtonItem(title: "UPLOAD", style: .plain, target: self, action: #selector(uploadHandler))

override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.setRightBarButton(uploadButton, animated: false)
}
...
}

  1. Initialize the button without an action and a selector, add them later in viewDidLoad:
class MyViewController: UIViewController {

private let uploadButton = UIBarButtonItem(title: "UPLOAD", style: .plain, target: nil, action: nil)

override func viewDidLoad() {
super.viewDidLoad()
uploadButton.target = self
uploadButton.action = #selector(uploadHandler)
self.navigationItem.setRightBarButton(uploadButton, animated: false)
}
...
}

There's very little difference among all these options, so it should be fine whatever one you choose.

A couple of side notes:

  • In my examples I declared uploadButton as private to indicate that it is not a part of your view controller's public API. If you need to access this button outside of your view controller, just remove the private modificator.
  • Animation doesn't get performed in viewDidLoad because your view is not yet on screen, so calling setRightBarButton(uploadButton, animated: true) will not trigger the animation, therefore I replaced true with false. If you want the user to see the animation, call it in viewDidAppear.

swift 3.0 UIBarButtonItem action not work


Swift 3.0

Declare UIBarButton inside ViewDidLoad()

override func viewDidLoad() {
super.viewDidLoad()
let logout: UIBarButtonItem = UIBarButtonItem.init(title: "Logout", style: .plain, target: self, action: #selector(ViewController.logOut))
}

func logOut() {
print("LogOut")
}

Declare UIBarButtonItem OutSide ViewDidLoad()

var logout:UIBarButtonItem = UIBarButtonItem()

override func viewDidLoad() {
super.viewDidLoad()
logout = UIBarButtonItem.init(title: "Logout", style: .plain, target: self, action: #selector(ViewController.logOut))
}

func logOut() {
print("LogOut")
}

Declare Completely Outside viewDidLoad()

lazy var logout: UIBarButtonItem = {
UIBarButtonItem.init(title: "Logout", style: .plain, target: self, action: #selector(ViewController.logOut))
}()

Any Should work.

For your action parameter either you can specify ViewController name explicitly or you can just say self.

action: #selector(self.logOut)

UIBarButtonItem Selector Function Not Being Called

Your function is not being called because:

If you use a closure to initialize a property, remember that the rest of the instance has not yet been initialized at the point that the closure is executed. This means that you cannot access any other property values from within your closure, even if those properties have default values.

moreover:

You also cannot use the implicit self property, or call any of the instance’s methods.

to solve this issue (cannot access to self during the initialization) you might declare such UIBarButtonItem as lazy var, so it will be created safely after the ViewController has been initialized:

lazy var addReminder:UIBarButtonItem = {
return UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(HomePageViewController.addNewReminder))
}()


Related Topics



Leave a reply



Submit