用动画重新加载表格视图单元格(Swift)

Posted

技术标签:

【中文标题】用动画重新加载表格视图单元格(Swift)【英文标题】:Reload Table view cell with animation (Swift) 【发布时间】:2015-04-14 16:20:08 【问题描述】:

有没有办法重新加载带有动画的多个部分的特定UITableView 单元格?

我一直在使用:

self.TheTableView.reloadSections(NSIndexSet(index: 1), withRowAnimation: UITableViewRowAnimation.Right)

不过,这会为该部分中的所有单元格设置动画。另一种选择是使用:

self.TheTableView.reloadRowsAtIndexPaths(<#indexPaths: [AnyObject]#>, 
                                         withRowAnimation: <#UITableViewRowAnimation#>)

编辑:

使用 reloadRowsAtIndexPaths 后

由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'无效更新:第1节中的行数无效。更新后现有节中包含的行数(5)必须等于行数更新前包含在该节中 (4),加上或减去从该节插入或删除的行数(0 插入,0 删除),加上或减去移入或移出该节的行数(0 移入, 0 移出)。'

试图通过将对象附加到数组中来找到一种重新加载 tableview 的平滑方法。

在 reloadRowsAtIndexPaths 工作之前调用 TheTableView.reloadData(),但动画有问题。还有其他方法吗?

【问题讨论】:

发生了什么!? 也许你应该看看这个帖子***.com/questions/20987585/… 【参考方案1】:

为什么不直接重新加载单元格? indexPath 包含节和行,因此只需跟踪要重新加载的节并填充该数组中的索引。

var indexPath1 = NSIndexPath(forRow: 1, inSection: 1)
var indexPath2 = NSIndexPath(forRow: 1, inSection: 2)
self.tableView.reloadRowsAtIndexPaths([indexPath1, indexPath2], withRowAnimation: UITableViewRowAnimation.Automatic)

根据您的评论,您希望更改数组并在更改中设置 tableView 动画。如果是这种情况,您应该考虑对 UITableViews 甚至 NSFetchedResultsController 使用 beginUpdates() 和 endUpdates() ,以便它干净地处理所有更新动画。

self.tableView.beginUpdates()
// Insert or delete rows
self.tableView.endUpdates()

如果您使用 Core Data,我建议您使用 NSFetchedResultsController,因为它可以简化整个过程。否则,您必须自己处理更改。换句话说,如果您的数组发生更改,您需要使用 beginUpdates() 和 endUpdates() 在 tableview 中手动删除或插入行。 如果您不使用 Core Data,请研究 this 以了解它是如何处理的。

【讨论】:

由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'无效更新:第1节中的行数无效。更新后现有节中包含的行数(5)必须相等更新前该节中包含的行数 (4),加上或减去从该节插入或删除的行数(0 插入,0 删除),加上或减去移入或移出该节的行数部分(0 移入,0 移出)。' 这可以工作,但我需要重新加载数据才能调用 reloadRowsAtIndexPaths。我会稍微摆弄一下。也许在该命令之前调用 ReloadData? 如果你想要一个干净的动画,你不能调用 reloadData。如果您的数据正在更改,请查看 beginUpdates() 和 endUpdates()。 UITableViewControllers 利用这一点使事情变得更容易(如果它适合您的应用模型) 所以我尝试了您的解决方案,但无论我将 beginUpdates() 和 endUpdates() 放在哪里,它似乎都无法解决崩溃问题。我基本上有一个 IBAction 将数据附加到一个数组中。这还需要重新加载 tableView 并仅对特定添加的单元格进行动画处理。 在调用 endUpdates 时(或者当您调用 reloadRowinsertRowsAtIndexPathsdeleteRowsAtIndexPaths 而不调用 beginUpdates 时,必须将委托设置为返回正确的行数和单元格请求。【参考方案2】:

在 Swift 3.0 中

我们可以在表格视图中重新加载特定部分的特定行

let indexPath = IndexPath(item: 2, section: 0)
self.tableView.reloadRows(at: [indexPath], with: .automatic)

【讨论】:

【参考方案3】:

如果你想在 swift 3.0 中重新加载单个部分,你可以这样做:

tableView.reloadSections(IndexSet(integer: 0), with: .automatic)

【讨论】:

【参考方案4】:

官方文档中定义IndexSet

管理整数值的Set,通常用作索引 输入 Cocoa API。有效整数值的范围是 在(0,INT_MAX-1)。超出此范围的任何内容都是错误。

所以IndexSet是关于索引的Set,只是把一些Int值放在[]中

// for reload one section
tableView.reloadSections([section], with: .automatic)
// or using like this
tableView.reloadSections(IndexSet(integer: section), with: .automatic)

// for reload multi sections
tableView.reloadSections([1, 2, 3, section], with: .automatic)

【讨论】:

请添加更多描述和/或有关您的答案以及它如何解决所问问题的信息,以便其他人可以轻松理解它而无需要求澄清 嗨 @koceeng ,我是 Swift 的新手。据我所知,IndexSet是一个关于索引的集合,官方文档在定义IndexSet时有说明: /// 管理一个Set的整数值,在Cocoa API中常用作索引类型。 /// 有效整数值的范围是 0.. 不要误会我的意思。您的回答在这里非常受欢迎,我们非常感谢。但是如果你提供一些细节/描述,它会更有趣,更容易理解。实际上,您在答案中提及您上面的评论非常好,您会看到。因为很多时候,寻求答案的人只是忽略了评论。您可以编辑您的答案并在上方添加您的评论。美好的一天:) 嗨@koceeng,事实上,我很担心我的英语不好。谢谢你的建议,我已经重新编辑了。

以上是关于用动画重新加载表格视图单元格(Swift)的主要内容,如果未能解决你的问题,请参考以下文章

如何在编辑表格视图单元格中的文本字段时重新加载所有表格视图单元格 - iOS Swift

使用 Swift 在表格视图中重新加载单元格数据

如何在单元格 Swift 2 中删除项目后重新加载表格视图

从自定义单元格重新加载表格视图数据

在表格视图中重新加载数据而不损害动画

以swift语言在自定义表格视图单元格中更新进度视图下载