iosswiftuibarbuttonitemtarget-action

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


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.


Solution

  • 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))