表视图数据被覆盖

问题描述 投票:0回答:2

我有一个UITableView。它的单元格包含将显示问题的标签,是按钮和否按钮。目的是一个一个地查看问题。首先,我调用API以在viewDidLoad方法中获取问题:

override func viewDidLoad() {
        super.viewDidLoad()
        tableView.allowsSelection = false

        getQuestions(baseComplainID: "1") { (questions, error) in
            self.questions = questions
            DispatchQueue.main.async {
                self.tableView.reloadData()
            }
        }
    }

在cellForRowAt方法中,我一一显示它们:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? TableViewCell else {
            fatalError("Fatal Error")
        }
        cell.yesButton.isHidden = false
        cell.noButton.isHidden = false

        if indexPath.row + 1 == displayNumber {
            cell.questionLabel.text = questions[indexPath.row].question_name
        } else {
            cell.yesButton.isHidden = true
            cell.noButton.isHidden = true
        }

        cell.yesButton.addTarget(self, action: #selector(action), for: .touchUpInside)
        cell.noButton.addTarget(self, action: #selector(action), for: .touchUpInside)

        return cell
    }

这是单击是或否时执行的操作:

@objc func action(sender: UIButton){
        let indexPath = self.tableView.indexPathForRow(at: sender.convert(CGPoint.zero, to: self.tableView))
        let cell = tableView.cellForRow(at: indexPath!) as? TableViewCell
        cell?.yesButton.isEnabled = false
        cell?.noButton.isEnabled = false

        if sender == cell?.yesButton {
            sender.setTitleColor(.black, for: .normal)
            sender.backgroundColor = .green
        } else {
            sender.setTitleColor(.black, for: .normal)
            sender.backgroundColor = .green
        }

        displayNumber += 1
        self.tableView.reloadData()
    }

在这里,我只是更改按钮的背景色并增加显示号以显示下一个问题。

当我滚动浏览时,所有这些都可以完美地工作,数据被覆盖,有时我发现问题标签为空,并且问题相互替换。由于单元的可重用性,我知道这是正常现象,但我不知道如何解决。

有什么建议吗?

ios swift uitableview tableview
2个回答
0
投票
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? TableViewCell else {
            fatalError("Fatal Error")
        }
        cell.yesButton.isHidden = false
        cell.noButton.isHidden = false

        if indexPath.row + 1 == displayNumber {
            cell.questionLabel.text = questions[indexPath.row].question_name
        } else {
            cell.yesButton.isHidden = true
            cell.noButton.isHidden = true
        }

        cell.yesButton.addTarget(self, action: #selector(action), for: .touchUpInside)
        cell.noButton.addTarget(self, action: #selector(action), for: .touchUpInside)

        return cell
    }

我感觉您的问题就在cellForRowAt函数中。

您已撰写此文

if indexPath.row + 1 == displayNumber { your code here }

但是我不确定为什么需要这个。

您应该在cellForRowAt内部执行类似的操作

let data = self.questions
data = data[indexPath.row]
cell.questionLabel.text = data.question_name

您不应该在indexPath.row中加1


0
投票

您将跟踪每个单元格的是与否。我会将枚举与您的问题一起添加到另一个数据结构中:

struct QuestionAndAnswer {
    enum Answer {
        case yes
        case no
        case nada
    }

    var question: Question
    var answer: Answer
}

并且在按下按钮时,请不要重新加载整个tableView。您只应重新加载已更改的行。在单元格上添加回调,以便您知道相应按钮属于哪个单元格。

class AnswerCell: UITableViewCell {
    @IBOutlet weak var yesButton: UIButton!
    @IBOutlet weak var noButton: UIButton!

    var onYes: (() -> Void)) = {}
    var onNo: (() -> Void)) = {}
}

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

    // ...

    sender.backgroundColor = .white

    cell.onYes = {
        sender.backgroundColor = .green
    }
    cell.onNo = {
        sender.backgroundColor = .green
    }

    // ...
}
© www.soinside.com 2019 - 2024. All rights reserved.