Visal
Visal

Reputation: 670

Change Navigation Bar Item Dynamically - Swift

I am creating a NavigationBar with UIBarButtonItem which located on right side of screen. As default I set that setRightBarButton with UIBarButtonItem(image: UIImage(named: "edit"), style: .plain, target: self, action: #selector(editProfile)) and when I clicked on that it should change that rightBarButton to other title but it doesn't work.

Here is I tried to change with I clicked on it

@objc
func editProfile() {
    self.navigationItem.setRightBarButton(cancelActionBar, animated: true)

}

This is object of cancelActionBar

let cancelActionBar = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(cancelEdit))

And this is its action which change it back to default.

@objc
func cancelEdit() {
    self.navigationItem.setRightBarButton(editActionBar, animated: true)
}

I also tried to use main thread as well but it is not working as I expected.

Upvotes: 1

Views: 2167

Answers (2)

RajeshKumar R
RajeshKumar R

Reputation: 15758

When you create a UIBarButtonItem as instance property the target self won't be initialized yet. So setting the target self won't work.

class ViewController: UIViewController {
    let editActionBar = UIBarButtonItem(title: "Edit", style: .plain, target: self, action: #selector(editBtnAction(_:)))
    override func viewDidLoad() {
        super.viewDidLoad()
        print(editActionBar.target)//nil
    }
}

The target self will be assigned properly when you initialize the button in viewDidLoad

class ViewController: UIViewController {
    var editActionBar: UIBarButtonItem?
    override func viewDidLoad() {
        super.viewDidLoad()
        editActionBar = UIBarButtonItem(title: "Edit", style: .plain, target: self, action: #selector(editBtnAction(_:)))
        print(editActionBar?.target)//self
    }
}

Declare the buttons as optional and initialize the buttons in viewDidLoad.

class ViewController: UIViewController {

    var editActionBar: UIBarButtonItem?
    var cancelActionBar: UIBarButtonItem?
    override func viewDidLoad() {
        super.viewDidLoad()
        self.editActionBar = UIBarButtonItem(title: "Edit", style: .plain, target: self, action: #selector(editBtnAction(_:)))
        self.cancelActionBar = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(cancelBtnAction(_:)))
        self.navigationItem.setRightBarButton(editActionBar, animated: true)
    }
    @objc func editBtnAction(_ sender: UIBarButtonItem) {
        self.navigationItem.setRightBarButton(cancelActionBar, animated: true)
    }
    @objc func cancelBtnAction(_ sender: UIBarButtonItem) {
        self.navigationItem.setRightBarButton(editActionBar, animated: true)
    }
}

Upvotes: 2

Khushbu
Khushbu

Reputation: 2430

In viewDidLoad method set edit as bar button

override func viewDidLoad() {
      self.setBarButton(isSetEditBarButton: true)
}

@objc func editProfile() {
    self.setBarButton(isSetEditBarButton: false)
}


@objc func cancelEdit() {
    self.setBarButton(isSetEditBarButton: true)
}


 private func setBarButton(isSetEditBarButton: Bool) {
     if isSetEditBarButton {
           let editActionBar = UIBarButtonItem(image: UIImage(named: "edit"), style: .plain, target: self, action: #selector(editProfile))
           self.navigationItem.setRightBarButton(editActionBar, animated: true)
     } else {
           let cancelActionBar = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(cancelEdit))
           self.navigationItem.setRightBarButton(cancelActionBar, animated: true)
     }
   }

Upvotes: 1

Related Questions