单元格重用后 UITableView 不更新 UIButton

Posted

技术标签:

【中文标题】单元格重用后 UITableView 不更新 UIButton【英文标题】:UITableView not updating UIButton after cell reuse 【发布时间】:2018-07-30 02:32:56 【问题描述】:

我有一个带有自定义单元格的 UITableView,称为 resultsCell。它包含 4 个 UILabel 和 6 个 UIButton,看起来像这样(我标记了每个框的类型):

UITableView 中大约有 10 个这样的单元格,所以这些单元格当然是被重用的。每当我向上和向下滚动多次时,单元格中的每个 UILabel 都会完美地更新到每个单元格,但是,UIButtons 并不总是正确更新,并且会显示不同的值。每个按钮都链接到一个 IBAction,该 IBAction 使用 segue 将用户重定向到不同的视图。如何修复 UIButtons 不更新?或者有没有更好的不带按钮的方法?

代码:

UITableViewCell 类:

class ResultsTableViewCell: UITableViewCell 
@IBOutlet weak var red1: UIButton!
@IBOutlet weak var red2: UIButton!
@IBOutlet weak var red3: UIButton!
@IBOutlet weak var redScore: UILabel!
@IBOutlet weak var blue1: UIButton!
@IBOutlet weak var blue2: UIButton!
@IBOutlet weak var blue3: UIButton!
@IBOutlet weak var blueScore: UILabel!
@IBOutlet weak var teamsLabel: UILabel!
@IBOutlet weak var scoreLabel: UILabel!

    override func prepareForReuse()  //I tried doing this with no luck.
        super.prepareForReuse()
        red1?.setTitle("", for: .normal)
        red2?.setTitle("", for: .normal)
        red3?.setTitle("", for: .normal)
        blue1?.setTitle("", for: .normal)
        blue2?.setTitle("", for: .normal)
        blue3?.setTitle("", for: .normal)
    


UITableView Dequeue Reusable Cell 代码

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCell(withIdentifier: "resultsCell") as! ResultsTableViewCell
    let thisMatch = resultsDict[indexPath.row] as! [String:String]
    cell.red1?.setTitle(thisMatch["red2"], for: .normal)
    cell.red2?.setTitle(thisMatch["red2"], for: .normal)
    cell.red3?.setTitle(thisMatch["red3"], for: .normal)
    cell.blue1?.setTitle(thisMatch["blue1"], for: .normal)
    cell.blue2?.setTitle(thisMatch["blue2"], for: .normal)
    cell.blue3?.setTitle(thisMatch["blue3"], for: .normal)
    cell.redScore?.text = thisMatch["redScore"]
    cell.blueScore?.text = thisMatch["blueScore"]
    if (playerID == thisMatch["red1"]) 
        cell.red1?.underline()
     else if (playerID == thisMatch["red2"]) 
        cell.red2?.underline()
     else if (playerID == thisMatch["red3"]) 
        cell.red3?.underline()
     else if (playerID == thisMatch["blue1"]) 
        cell.blue1?.underline()
     else if (playerID == thisMatch["blue2"]) 
        cell.blue2?.underline()
     else if (playerID == thisMatch["blue3"]) 
        cell.blue3?.underline()
    

    return cell    

这个匹配


        "red1": "1234",
        "red2": "4567",
        "red3": "8901",
        "blue1": "2345",
        "blue2": "6789",
        "blue3": "0123",
        "redScore": "456",
        "blueScore": "789",

按钮应该显示什么:

下划线扩展:

extension UIButton 
func underline() 
    let attributedString = NSMutableAttributedString(string: (self.titleLabel?.text!)!)
    attributedString.addAttribute(NSAttributedString.Key.underlineStyle,
                                  value: NSUnderlineStyle.single.rawValue,
                                  range: NSRange(location: 0, length: (self.titleLabel?.text!.count)!))
    self.setAttributedTitle(attributedString, for: .normal)



【问题讨论】:

@matt 对不起,我把我的代码复制错了。我实际上设置了 6 个按钮,并更新了上面的代码。我还测试了有标签而不是按钮,来自resultsDict[indexPath.row] 的信息更新正确,所以它不是信息。 尝试将thisMatchindexPath.row 记录下来,看看它是否显示出与您的预期不同的任何内容。如果您使用上述代码,thisMatch 的值很有可能是错误的。 @matt 好的,我会记录thisMatchindexPath.row 看看是否有误。我还会分享thisMatch是什么以及按钮显示的截图 @adev 我尝试在控制台中记录它,我得到了我期望的结果,但是按钮的值不正确 @matt 我追溯了每个出口,并且它们设置正确。我在问题中包含了thisMatch 包含的内容。按钮显示red1red2red3blue1blue2blue3。我还记录了它应该显示的内容和indexPath.row,它记录了我期望的结果,但按钮显示的数字完全不同 【参考方案1】:

每个按钮都是重复使用的,所以我们也应该指定不带下划线的大小写。试试这个代码。

 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCell(withIdentifier: "resultsCell") as! ResultsTableViewCell
    let thisMatch = resultsDict[indexPath.row] as! [String:String]

    cell.redScore?.text = thisMatch["redScore"]
    cell.blueScore?.text = thisMatch["blueScore"]


    if (playerID == thisMatch["red1"]) 
        cell.red1?.setTitle(thisMatch["red1"], for: .normal)
        cell.red1?.underline()
     else 
       cell.red1?.setTitle(thisMatch["red1"], for: .normal)
    


    if (playerID == thisMatch["red2"]) 
        cell.red2?.setTitle(thisMatch["red2"], for: .normal)
        cell.red2?.underline()
    else 
        cell.red2?.setTitle(thisMatch["red2"], for: .normal)
    

    if (playerID == thisMatch["red3"]) 
        cell.red3?.setTitle(thisMatch["red3"], for: .normal)
        cell.red3?.underline()
     else 
        cell.red3?.setTitle(thisMatch["red3"], for: .normal)
    

    if (playerID == thisMatch["blue1"]) 
        cell.blue1?.setTitle(thisMatch["blue1"], for: .normal)
        cell.blue1?.underline()
     else 
        cell.blue1?.setTitle(thisMatch["blue1"], for: .normal)
    

    if (playerID == thisMatch["blue2"]) 
        cell.blue2?.setTitle(thisMatch["blue2"], for: .normal)
        cell.blue2?.underline()
    else 
        cell.blue2?.setTitle(thisMatch["blue2"], for: .normal)
    

     if (playerID == thisMatch["blue3"]) 
        cell.blue3?.setTitle(thisMatch["blue3"], for: .normal)
        cell.blue3?.underline()
      else 
        cell.blue3?.setTitle(thisMatch["blue3"], for: .normal)
    

    return cell

【讨论】:

感谢您的回答,但不幸的是,当单元格重复使用时,它不会删除下划线,并且按钮中的数字会不断变化 这个循环有问题,如果 (playerID == thisMatch["red1"]) ,我编辑了答案。试试这个并尝试删除准备重用代码。 非常感谢。我会尽快尝试并让您知道它是否有效。 :)

以上是关于单元格重用后 UITableView 不更新 UIButton的主要内容,如果未能解决你的问题,请参考以下文章

UITableView 不重用单元格?

UITableView - 在编辑模式下重用单元格

UITableView 单元格中的可重用单元格存在问题

Swift - uitableview 重用单元格时用户输入混淆?

UITableView 不使用情节提要重用单元格

swift in UI test(测试UITableView中的单元格数)