移出可见的 uitableView 后,UITableViewCell 具有灰色背景

Posted

技术标签:

【中文标题】移出可见的 uitableView 后,UITableViewCell 具有灰色背景【英文标题】:TableViewCell has grey background after movement out of visible tableView 【发布时间】:2018-10-15 09:29:20 【问题描述】:

以下测试应用显示了一个简单的 tableView。原型单元格的属性selectionStyle 设置为default(灰色)。由于单元格的数量超出了可以显示的范围,因此第一个单元格可见,最后一个单元格不可见。每个单元格的背景颜色设置为白色。

第一次测试: When one of the cells is selected, its background becomes grey. 在委托函数中,其isSelected 属性随后设置为false,因此单元格背景再次变为白色。然后将单元格移动到第 0 行,并相应地更新数据源。 这按预期工作。

第二次测试: tableView 向上滚动,以便最后一个单元格可见。 当一个单元格现在被选中时,它会再次移动到第 0 行,该行已移出 tableView 的可见区域。这再次起作用。但是: 如果随后向下滚动 tableView 以使第 0 行再次可见,移动的单元格现在具有灰色背景,就好像它被选中,但事实并非如此。这没有按预期工作:

这是我的代码:

import UIKit

class ViewController: UIViewController 
    @IBOutlet weak var tableView: UITableView!
    var tableData = ["00", "01", "02", "03", "04", "05", "06", "07", "08", "09", 
                     "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"]


extension ViewController: UITableViewDataSource 
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return tableData.count
    

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCell(withIdentifier: "TableViewCell")!
        let row = indexPath.row
        cell.textLabel?.text = tableData[row]
        cell.backgroundColor = .white
        return cell
    


extension ViewController: UITableViewDelegate 
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
        let selectedCell = tableView.cellForRow(at: indexPath)!
        selectedCell.isSelected = false

        let sourceRow = indexPath.row
        let destinationRow = 0

        let removedElement = tableData.remove(at: sourceRow)
        tableData.insert(removedElement, at: 0)

        let destinationIndexPath = IndexPath.init(row: destinationRow, section: 0)
        tableView.moveRow(at: indexPath, to: destinationIndexPath)
    

我的问题: 我的代码有什么问题吗? 或者这是一个ios错误?如果是这样,是否有解决方法?

请注意: 当然可以使用tableView.reloadData() 代替tableView.moveRow(at:, to:)。然后,移动的单元格没有灰色背景。但在这种情况下,运动不是动画的,因为我在开发中的应用程序中需要它。 如果原型单元格的属性selectionStyle 设置为none,则移动的单元格既没有灰色背景,也没有可见的选择反馈。

【问题讨论】:

isSelected 属性设置为false 同时出队作为一种解决方法? 感谢您的提示。我在出队后立即这样做了,但灰色背景仍然存在。其实我之前检查过,出队后没有选择单元格。 【参考方案1】:

不设置isSelected属性,而是调用UITableView的deselectRow(at:animated:)方法:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
    tableView.deselectRow(at: indexPath, animated: true)
    ...

【讨论】:

我不知道设置isSelected = falsetableView.deselectRow(at: , animated:) 不同,但第二个显示了预期的结果。谢谢!【参考方案2】:

我向 Apple 提交了错误报告并收到以下答复:

您通常应该始终使用 deselectRow(at:animated:) 方法 在 UITableView 上取消选择一行。如果您只更改选定的 当前直接为该行显示的 UITableViewCell 上的属性, 表格视图不会意识到这一点,并且当一个新单元格 在滚动期间重复用于同一行,表格视图将重置 单元格的选定状态以匹配它是否认为该行是 选择。表格视图的状态始终是事实的来源;这 细胞状态只是一个当前的视觉表示 特定的行。

很高兴知道!

【讨论】:

以上是关于移出可见的 uitableView 后,UITableViewCell 具有灰色背景的主要内容,如果未能解决你的问题,请参考以下文章

iOS UITableViews - 将部分的标题移出屏幕

UITableView 中的自定义绘图在 5 个单元格后失败

UITableView 在点击屏幕之前不可见

UITextField 成为第一响应者后,UITableView 不会将单元格滚动到可见

UITableView 标头不可见

UITableview如何一次只显示一个单元格