How to get a bar button item to update based on user cell taps

I am creating a quiz app where each question in the quiz is presented by a tableview embedded in a navigationcontroller. I have a score label set in the right bar button item of the navigation controller that I want to update each time a user chooses an answer (tableviewcells). I can't seem to get the score label to update with my code.. Any thoughts?


Btw there is more stuff in my viewDidLoad but i just kept the relevant stuff in for the code snippet.

var score: Int = 0 {
     didSet {
          navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Score: \(score)", style: .plain, target: nil,
          action: Selector(("updateScore")))
     }
}

override func viewDidLoad() {
     super.viewDidLoad()

     score = 0
}

@objc func updateScore() {
     var newScore = score
     for question in questionsList {
          if question.selectedAnswerIndex == question.correctAnswerIndex {
               newScore += 1
          }
     }

     score = newScore

}


Also the selectedAnswerIndex and correctAnswerIndex comes from my question model class that contains the quiz questions in my questionsList array. Is this possible to do with a bar button item or should I be looking into other ways to represent the score..?

Replies

You create a new instance of navigationItem.rightBarButtonItem each time you change the value.


You should just upfdate the existing navigationItem.rightBarButtonItem

I'm a little confused. Isn't the updateScore method updating the existing rightBarButtonItem? How do I change my code so it doesn't create a new instance of rightBarButton each time?

You can try something like this:

    var score: Int = 0 {
        didSet {
            navigationItem.rightBarButtonItem?.title = "Score: \(score)"
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Score: \(score)", style: .plain,
            target: self, action: #selector(updateScore))
    }

As far as I tested with iOS 12.4 simulator in Xcode 10.3, the title of the right bar button item is updated each time `score` is set.

But I am not sure if this is the right way, as the doc says

Discussion


You should set this property before adding the item to a bar. The default value is

nil
.


or should I be looking into other ways to represent the score..?

Maybe you should.


Some points:

- When you set target as nil, no action will be performed

- Do not use the initializer of `Selector`, such as `Selector(("..."))`, use `#selector` as far as possible

No, you are not just updating.

When you call

navigationItem.rightBarButtonItem = UIBarButtonItem

you create a new instance.

You have to change the title of the existing item, not create a new one.