Swift UITableView 在 reloadData() 之后搞砸了

Swift UITableView messing up after reloadData()

我正在开发一个 iOS 应用程序,我想从另一个控制器重新加载 UITableView 的信息。为了做到这一点,我在另一个名为 (AirlinesController).

的控制器中引用了控制器 MainViewControllerUITableView

我在重新加载第一个控制器的 UITableView 的数据时遇到问题,它几乎搞砸了:

MainViewController

您可以看到 table 的每个单元格都指向 AirlinesController:

AirlinesController

所以在用户点击“应用”按钮后,MainViewControllerUITableView 使用 mainView.reloadData() 重新加载。在此示例中,我希望在 MainViewController 中看到标题为“Embraer”的单元格有一个带有文本“已完成”的绿色标签,标题为“Airbus”的单元格有一个带有标题的黄色标签“员工”,但这是我重新加载 table:

后得到的结果

为什么 table 的最后一个单元格将其中一个标签颜色更改为黄色?

这是我正在使用的代码:

MainViewController

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "itemCell", for: indexPath) as! CellController
    
    let items = self.gameView.data!.levels
    
    cell.model.text = items[indexPath.row].name
    
    if items[indexPath.row].id < self.gameView.game!.level.id {
        cell.cost.text = "Complete"
        cell.cost.textColor = UIColor.systemGreen
        cell.accessoryType = .none
        cell.isUserInteractionEnabled = false
    } else if items[indexPath.row].id == self.gameView.game!.level.id {
        cell.cost.text = "Employee"
        cell.cost.textColor = UIColor.systemYellow
        cell.accessoryType = .none
        cell.isUserInteractionEnabled = false
    } else {
        cell.cost.text = "\(items[indexPath.row].XP) XP"
    }

    return cell
}

AirlinesController

@IBAction func apply(_ sender: Any) {
    if (mainView.game.XP >= level.XP) {
        let new_salary = Int(Float(mainView.game.salary) * level.salaryMultiplier)
        let new_XP = Int(Float(mainView.game.XPSalary) * level.XPMultiplier)
        mainView.game.salary = new_salary
        mainView.game.XPSalary = new_XP
        mainView.salaryLabel.text = "\(new_salary) $"
        mainView.XPLabel.text = "\(new_XP) XP"
        
        mainView.workingFor.text = "Currently working for \(level.name)"
        
        mainView.game.level = Level(id: level.id, name: level.name, XP: 0, XPMultiplier: 1, salaryMultiplier: 1, aircrafts: [Aircraft]())
        
        mainView.saveGame()
        
        DispatchQueue.main.async {
            self.mainView.levelItems.reloadData()

            self.navigationController?.popViewController(animated: true)
        }
    } else {
        let alert = UIAlertController(title: "Error", message: "Not enough experience to apply!", preferredStyle: UIAlertController.Style.alert)
        alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.cancel, handler: nil))

        self.present(alert, animated: true)
    }
}

我该如何解决这个问题?

这是因为单元格的重复使用。

设置else条件下的默认颜色。

} else {
  cell.cost.textColor = UIColor.gray
  cell.cost.text = "\(items[indexPath.row].XP) XP"
}

另一种方式,可以在UITableViewCell

prepareForReuse方法里面设置默认样式属性
class TableViewCell: UITableViewCell {
    override func prepareForReuse() {
        super.prepareForReuse()
        // Set default cell style
    }
}

TableViewCell 一直重复使用。我的建议是每次都必须设置默认颜色。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "itemCell", for: indexPath) as! CellController

cell.cost.textColor = ...your default text color....

...
return cell