重新加载 tableView 部分而不重新加载标题部分 - Swift

Posted

技术标签:

【中文标题】重新加载 tableView 部分而不重新加载标题部分 - Swift【英文标题】:Reload tableView section without reloading header section - Swift 【发布时间】:2015-09-07 14:21:09 【问题描述】:

我正在尝试重新加载 tableView 部分,而不是重新加载整个 tableview,因为我在标题部分中有一个文本字段,当我调用 self.tableView.reloadData() 时,我的键盘关闭了。

我已经尝试了下面的代码,但我收到了这个错误Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to delete row 5 from section 2 which only contains 4 rows before the update' 那么请问我的问题在哪里?

    let newCount = self.placeArray.count

    var newIndexPaths = NSMutableArray(capacity: newCount)

    for var i = 0 ; i < newCount ; i++ 
    var indexPath = NSIndexPath(forRow: i, inSection: 2)
        newIndexPaths.addObject(indexPath)
    

    self.tableView.beginUpdates()
    self.tableView.reloadRowsAtIndexPaths(newIndexPaths as [AnyObject], withRowAnimation: UITableViewRowAnimation.None)
    self.tableView.endUpdates()

【问题讨论】:

这样的代码容易造成不一致,不要害怕调用datasource方法获取行数。 @A-Live 对不起,我不明白怎么做? 使用numberOfRowsInSection 而不是从那里复制逻辑,这样数字必须始终正确。您没有显示或提及对行数的任何修改,所以我假设您没有这样做,否则您必须根据获取数字和修改数据源的时间来相应地更改数字。 我认为你给了我解决方案,但我没有得到你。我正在用新数组更新numberOfRows。 @A-Live 您尝试更新的行数多于实际行数,表格视图假定您尝试删除一行 - 这是由于您在计算行数时的错误造成的。 【参考方案1】:

您可以改用UITableViewreloadSections 方法。

tableView.reloadSections(IndexSet(integer: 2), with: .none)

【讨论】:

如何更新节的页眉和页脚:***.com/questions/46531768/… 出于某种原因,我必须在 Swift 3 中将 NSIndexSet 转换为 IndexSet:self.myTableView.reloadSections(NSIndexSet(index: index) as IndexSet, with: .automatic) 这将重新加载部分和部分 headerView。我对这个答案的支持感到惊讶 这不是正确的答案,它正在重新加载节标题但它只是没有动画 这不是正确的答案。这会重新加载整个部分,包括标题【参考方案2】:

Swift 3.0.1:

let sectionIndex = IndexSet(integer: 0)

tableView.reloadSections(sectionIndex, with: .none) // or fade, right, left, top, bottom, none, middle, automatic

【讨论】:

这也是重新加载标题。 如果你把它做成动画,你可以很清楚地看到它重新加载了节标题【参考方案3】:

Swift 3.1 Xcode 8.3.3 答案:)

问题是 - 每个部分当然包括标题,所以部分是:

部分 = 页眉 + 页脚 + 行

答案是 - 通过 IndexPath 直接重新加载行。 示例:

    假设您的表格中有 1 个部分,并且您将其用作表格的数据源的“数组”:

    let indexes = (0..&lt;array.count).map IndexPath(row: $0, section: 0)

    现在我们有了要重新加载的单元格索引数组,所以:

    tableView.reloadRows(at: indexes, with: .fade)

【讨论】:

【参考方案4】:

注意:

UITableView.reloadData() 将重新加载所有表格。 Docs about reloaddata

重新加载用于构建表的所有数据,包括 单元格、节页眉和页脚、索引数组等。为了 效率,表格视图只重新显示那些 可见的。如果表格由于以下原因而缩小,它会调整偏移量 重新加载。表视图的委托或数据源调用此方法 当它希望表视图完全重新加载其数据时。

UITableView.reloadSections(_ sections: IndexSet, with animation: UITableViewRowAnimation) 将重新加载特定部分(包括部分页眉和部分页脚)。 Docs about reloadsections

UITableView.reloadRows(at indexPaths: [IndexPath], with animation: UITableViewRowAnimation) 将重新加载指定的行。 Docs about reloadRows

所以这里reloadSections 在这里不起作用。 如果你的header section的数据和状态没有改变,调用这个方法不会有什么区别。

解决方案:使用reloadRows 加载所有节或特定节的行。 注意:这里你可以只加载可见的行,滚动查看时会加载其他行。您也可以参考Get all indexPaths in a section了解更多解决方案

var indexPaths = self.tableView.indexPathsForVisibleRows

/* just roload visible rows of specified section
indexPaths = indexPaths.filter( (indexPath) -> Bool in
    return indexPath.section == SECTION_INDEX_NEED_TO_RELOAD
)
*/
self.tableView.reloadRows(at: indexPaths!, with: .none)

【讨论】:

嘿,好的答案和好的文档。但是当我调用reloadRows 时,我的标题也会重新加载,在我的情况下,我的标题是隐藏的。如果您对此特定问题有任何解决方案,请告诉我。【参考方案5】:

斯威夫特 5

您可以按如下方式重新加载部分:

tableView.reloadSections([0], with: .none)

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

这里表示它将重新加载的索引。

重新加载多个部分:

tableView.reloadSections([0, 1, 3], with: .none)

【讨论】:

【参考方案6】:

斯威夫特 5

这里放的是静态索引重新加载,这是第一个索引,您可以根据需要进行更改。

self.tblView.reloadSections(IndexSet(index: 1), with: .none)

【讨论】:

为什么选择 NSIndexSet?我可以使用索引集 感谢您的建议,我刚刚更新了我的答案。【参考方案7】:

[斯威夫特 5]

您想重新加载一个部分中的所有行。所以你可以这样做:

let rowIndexes: [IndexPath] = Array(0...YOUR_ARRAY-1).map( 
    return IndexPath(row: $0, section: YOUR_SECTION) 
)

获取此部分的所有可能的行索引。然后你只需要为这些索引重新加载行:

tableView.reloadRows(at: rowsIndexes, with: .fade)

该部分不会重新加载。

【讨论】:

【参考方案8】:

我可能迟到了,但这里有一个二维数组的解决方案(如果你的 tableView 有部分并且每个部分都有一些项目)。这将重新加载每个部分中的每个单元格,但不会触及该部分的页眉/页脚。

    let indexPaths = (0..<array.count).map  section in
        (0..<array[section].nestedArray.count).map  IndexPath(row: $0, section: section) 
    .flatMap  $0 
    tableView.reloadRows(at: indexPaths, with: .fade)

【讨论】:

以上是关于重新加载 tableView 部分而不重新加载标题部分 - Swift的主要内容,如果未能解决你的问题,请参考以下文章

重新加载 UITableView 而不重新加载标题部分

每秒重新加载 Tableview 部分会导致闪烁

在没有滚动或动画的情况下重新加载 tableview 部分

分组 TableView,使用自定大小的部分标题,重新加载后,如果我向上滚动,tableview 会跳转

TableView:是不是可以在不重新加载 tableview 或部分的情况下删除现有行并插入新行?

每次我重新加载 tableview 部分时 UITableView 都不会向上滚动