Why adding barBarttonItem won’t work if created out of scope where it’s added?

125 Views Asked by At

I ran into some problems when adding barButtons and found the solution in the answer to another question, but the it didn’t explain why you must create and add the buttons in the same scope. I want to know why you can’t create the buttons in class level and add them in a method like viewDidLoad. Example code that doesn’t work from that question copied below:

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
}

This get an error that won’t recognize the @objc methods(not included here). There’s nothing wrong with those methods, as when you move the button-creations inside viewDidLoad the error disappears and the code works.

2

There are 2 best solutions below

4
Robert Dresler On BEST ANSWER

These bar button properties are created before init is called and you're trying to access class methods which can't be called before init is called.

If you want to initialize your buttons on class scope, you will have to make them lazy variables in order to create them when they are needed

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))
0
Deviyani Swami On
     override func viewDidLoad() {
        super.viewDidLoad()

        let leftBarButton = UIBarButtonItem(title: "Left Button", style: .plain, target: self, action: #selector(pressOnleftBarButton))
        navigationItem.leftBarButtonItem = leftBarButton

        let rightBarbutton = UIBarButtonItem(title: "Right Button", style: .plain, target: self, action: #selector(pressOnRightBarButton))
        navigationItem.rightBarButtonItems = rightBarbutton
    }

    @objc func pressOnleftBarButton(){
      //Perform Action on Left Button
    }

    @objc func pressOnRightBarButton(){
        //Perform Action on right Button
    }