UIBarButtonItem selector not working

2020-02-15 10:04发布

问题:

I have a MainViewController embed in a Navigation Controller, as shown below:

And in MainViewController.swift, I added two UIBarButtonItem(left and right) programmatically:

class MainViewController: UIViewController {

    let rightButton = UIBarButtonItem(title: "Right", style: .plain, target: self, action: #selector(onRightClick))
    let leftButton = UIBarButtonItem(title: "Left", style: .plain, target: self, action: #selector(onLeftClick))

    override func viewDidLoad() {
        super.viewDidLoad()
        navigationItem.rightBarButtonItem = rightButton
        navigationItem.leftBarButtonItem = leftButton
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    @objc func onRightClick() {
        print("[Main] Right Click")
    }

    @objc func onLeftClick() {
        print("[Main] Left Click")
    }
}

The buttons did show on the screen, but the interesting thing is, the selector functions onLeftClick and onRightClick never get called whenever I pressed left or right button. Is there anything I should do to make it works? I am using Xcode 9.3.

回答1:

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
    }
}


回答2:

You can also just add the lazy keyword to the rightButton and leftButton class properties. That way, the UIBarButtonItem won't be instantiated (and the action selectors won't attempt to be resolved) until they are used inside the class. Doing it this way allows you to use the barButtonItems anywhere in the class (not just in the function they are declared in).

lazy var rightButton = UIBarButtonItem(title: "Right", style: .plain, target: self, action: #selector(onRightClick))
lazy var leftButton = UIBarButtonItem(title: "Left", style: .plain, target: self, action: #selector(onLeftClick))