0

I am trying to create a tableview that selects the cell using an indexPath.

I have saved the indexPath of selected cell & save it to my data array for each question. However when I reload the tableView how do I get the indexPath to change that particular cell's background view to how it looked when I select the previous button.

var dataArray: [MultipleChoice] = [
    MultipleChoice(
        question: "Question 1",
        options: ["Answer 1", "Answer 2", "Answer 3", "Answer 4"],
        rightAnswer: "Answer 1",
        subject: "General",
        idxPath: [0,0]),
    MultipleChoice(
        question: "Question 2",
        options: ["Answer 1", "Answer 2", "Answer 3", "Answer 4"],
        rightAnswer: "Answer 2",
        subject: "General",
        idxPath: [0,0]),


@IBAction func nextButtonPressed(_ sender: Any) {

    if var index = dataBrain.questionNumber {
        if index + 1 < dataBrain.dataArray.count {

            index += 1
            dataBrain.questionNumber = index
            scoreLabel.text = "\(dataBrain.questionNumber! + 1)/\(dataBrain.dataArray.count)"
            answerHidden = true
            table.reloadData()

        } 

}

@IBAction func previousButtonPressed(_ sender: Any) {

    if var index = dataBrain.questionNumber {
        if index - 1 >= 0 {

            index -= 1
            dataBrain.questionNumber = index
            scoreLabel.text = "\(dataBrain.questionNumber! + 1)/\(dataBrain.dataArray.count)"
            table.reloadData()

        }

}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCell(withIdentifier: AnswerTableViewCell.identifier) as! AnswerTableViewCell

        //Load Options:
        if let index = dataBrain.questionNumber {
            let data = dataBrain.dataArray[index]
            cell.answerLabel.text = data.options![indexPath.row - 1]
            cell.selectionStyle = .none
        }

        //Load Right/Wrong Options
        let index = dataBrain.questionNumber
        let data = dataBrain.dataArray[index!]
        let rightAnswer = data.rightAnswer!

        if cell.answerLabel.text == rightAnswer {
            cell.confirmButton.setImage(UIImage(systemName: "checkmark.circle"), for: .normal)
            cell.confirmButton.imageView?.tintColor = UIColor.green
        } else {
            cell.confirmButton.setImage(UIImage(systemName: "xmark.circle"), for: .normal)
            cell.confirmButton.imageView?.tintColor = UIColor.red
        }

        //Load Background Color/Text
        cell.delegate = self
        cell.selectedBackgroundView = .none
        cell.confirmButton.isHidden = answerHidden

        let selectedCell = dataBrain.dataArray[index!].idxPath
        if selectedCell == [0,0] {
            cell.answerView.backgroundColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
            cell.answerLabel.textColor = #colorLiteral(red: 0.4228360057, green: 0.4478931427, blue: 0.4731111526, alpha: 1)
        } else {
            table.selectRow(at: selectedCell, animated: false, scrollPosition: .none)
        }

        return cell

enter image description here enter image description here enter image description here

Captain725
  • 73
  • 1
  • 7

1 Answers1

3

When you implement tableView(_ tableView: UITableView, cellForRowAt ..., your job is to return a cell for the given indexPath -- do not change the table. Your source of truth is dataBrain.dataArray -- get the information, put it in a cell, and return it. That's it.

So, in this code:

let selectedCell = dataBrain.dataArray[index!].idxPath
if selectedCell == [0,0] {
    cell.answerView.backgroundColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
    cell.answerLabel.textColor = #colorLiteral(red: 0.4228360057, green: 0.478931427, blue: 0.4731111526, alpha: 1)
} else {
    table.selectRow(at: selectedCell, animated: false, scrollPosition: .none)
}

The if should be more like this:

if selectedCell[0] == indexPath.section, selectedCell[1] == indexPath.row {
    // The cell I am making is selected -- set it up
} else {
    // The cell I am making is not selected, set it up also
    // (it could be a reused cell that is colored for selection, so ALWAYS set the properties.
}

Do not call table.selectRow

Now, when you want a cell to change, just reload it. Either reloadData (not ideal, but you can do it to make sure things work), or the other reload methods that target specific changes.

Lou Franco
  • 87,846
  • 14
  • 132
  • 192