UITableView 在删除一行或多行后留下空白单元格的模式

Posted

技术标签:

【中文标题】UITableView 在删除一行或多行后留下空白单元格的模式【英文标题】:UITableView leaves pattern of blank cells after deleting one or more rows 【发布时间】:2019-01-27 19:20:44 【问题描述】:

TableView leaving blank cells

Repeating blank cells

When deleting rows from the bottom

在我的 TableView 中删除一行或多行后,TableView 单元格似乎会以一种奇怪的方式移动或刷新,从而创建多个空白行。似乎从屏幕外的行开始。

我已尝试使用 beginUpdates、endUpdates 和 performBatchUpdates,但行为没有改变。我还确认数据源数组正在正确更新,tableview 中的行数也是如此。

func numberOfSections(in tableView: UITableView) -> Int 
    return 1


func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return paymentsArray.count


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

    let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! UserPaymentCell

    let payment = paymentsArray[indexPath.row]
    cell.payment = payment

    cell.selectionStyle = .none

    cell.preservesSuperviewLayoutMargins = false
    cell.separatorInset = UIEdgeInsets(top: 0, left: 75, bottom: 0, right: 0)
    cell.layoutMargins = UIEdgeInsets.zero

    return cell


func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat 
    return 100



func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool 

    let payment = paymentsArray[indexPath.row]

    if payment.payerUID == Auth.auth().currentUser?.uid 
        return true
     else 
        return false
    


func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) 

    let payment = paymentsArray[indexPath.row]

    switch editingStyle 
    case .delete:
        deleteBillAndRefreshTotals(bill: payment, indexPath: indexPath)
    default:
        return
    


func deleteBillAndRefreshTotals(bill: Bill, indexPath: IndexPath) 
    print("DELETING CELL")
    paymentsArray.remove(at: indexPath.row)
    paymentsTableView.deleteRows(at: [indexPath], with: .automatic)
    print(paymentsTableView.numberOfRows(inSection: 0))

预期结果 - 要删除的行以及已删除单元格上方或下方的所有单元格一起移动。

【问题讨论】:

可以看看数据源方法吗? @matt 为你包含了数据源方法! 嗯,我看不出有什么问题,除了 deleteRows 应该包裹在 performBatchUpdates 中。如果这不能解决它,您可以发布一个演示该问题的小型测试项目吗?基本上它应该只包含您已经发布的代码。 顺便说一下,这是我的可下载示例项目,您可以看到它没有显示此问题。 github.com/mattneub/Programming-ios-Book-Examples/tree/master/… 【参考方案1】:
override func prepareForReuse() 
    super.prepareForReuse() // <--
    self.nameLabel.text = nil
    self.backgroundColor = .white

在我的自定义单元实现中,调用上述函数没有首先调用super.prepareForReuse。因此导致上述问题。

【讨论】:

【参考方案2】:
after perform delete operations call reloaddata method so after that tableview will refresh.
 func deleteBillAndRefreshTotals(bill: Bill, indexPath: IndexPath) 
    print("DELETING CELL")
    paymentsArray.remove(at: indexPath.row)
    paymentsTableView.reloaddata()
    print(paymentsTableView.numberOfRows(inSection: 0))

【讨论】:

【参考方案3】:

你可以试试这个代码:

paymentsTableView.beginUpdates()
paymentsTableView.deleteRows(at: [indexPath], with: .automatic)
paymentsTableView.endUpdates()

【讨论】:

感谢您的建议。我已经尝试过了,它仍然显示相同的行为,以及 performBatchUpdates。 @chenders 我在等你提供可重现的示例项目。 @matt 不确定发布小样本的最佳方式。您只需要 GitHub 上完整项目的链接吗? @chenders 重点是让您在一个普通的小型项目中重现该问题并在 github 上发布 那个。你看,我假设你无法做到——因为问题是由于你没有向我们展示的真实项目中其他地方的完全不同的代码。我挑战你在一个minimal项目中向我展示这个问题,而不是你的完整项目。我向展示了一个演示项目,这个问题不会发生。现在你给我看一个演示项目。 @matt 我按照你的建议做了,但没有重现问题。所以我研究了它与自定义单元格本身有关的可能性。果然,我查看了我之前的 prepareForReuse 函数……将其注释掉,它的工作原理应该是这样的。很快意识到我没有首先在函数中调用 super.prepareForReuse,导致我的一些单元格变为空白单元格。感谢您建议将其全部剥离!

以上是关于UITableView 在删除一行或多行后留下空白单元格的模式的主要内容,如果未能解决你的问题,请参考以下文章

从标签页中删除标签栏会留下空白。如何删除它?

UIImageView 上的方面适合在 UITableView 单元格中留下大量空白

拖动时删除 UITableView 和 UIRefreshControl 之间的空白

如何从 UITableView 中删除一行

尝试移动 UITableView 行时崩溃

删除 UITableView 中的行时出错