user11601508
user11601508

Reputation:

How to update a UINavigationItem based on UITableViewCell taps?

I am creating a Quiz app where each quiz question is a grouped TableView with each cell being an answer choice, and is embedded in a navigation controller. For each right answer a user taps, I want their score to go up by 1. I have set up a score label as a rightBarButtonItem in my navigation controller.

Here is what I have for creating the bar button item in viewDidLoad( ):

navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Score: \(score)", style: .plain, target: nil, action: Selector(("updateScore")))

I have a model class Question that contains an array questionsList which includes the properties: questionString, answers[], selectedAnswerIndex (nil), and correctAnswerIndex (int)

The updateScore method:

@objc func updateScore() {

        for question in questionsList {

            if question.selectedAnswerIndex == question.correctAnswerIndex {
                score += 1
            }
        }
    }

Any thoughts? I tried doing this another way by putting the score label in a footerview, using viewForFooterInSection for the table controller, and also putting the for loop in my didSelectRowAt method but the score label wouldn't update there either.

Upvotes: 1

Views: 74

Answers (1)

rmaddy
rmaddy

Reputation: 318824

After you update score, you need to create and assign a new bar button item. You can't update the text of the existing button.

After your for loop, add:

navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Score: \(score)", style: .plain, target: nil, action: Selector(("updateScore")))

Yes, it's the same code as what you show for creating the original button.

A better approach would be to update your score property:

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

Then update your updateScore:

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

    score = newScore
}

Then update viewDidLoad (or wherever) and remove the current call to create the bar button item and simply do:

score = 0 // or some other appropriate initial value

Upvotes: 1

Related Questions