UITableView重新加载section。

49

我希望重新加载一个部分而不是整个表格。在UITableView中有没有相应的方法。

[tableView reloadData]用于加载整个表格。
我想知道如何只加载一个部分,因为我的表格中有大量的行。


2
调用reloadData仍然只会重新加载当前屏幕上的UITableViewCells。 - james_womack
可能是 https://dev59.com/pU_Ta4cB1Zd3GeqPDsfz 的重复问题。 - Ankit Srivastava
11个回答

71

reloadSections方法让我感到困扰--因为我必须构建一些对象。如果需要灵活性,这很棒,但有时也只是想要简单性。它的用法如下:

NSRange range = NSMakeRange(0, 1);
NSIndexSet *section = [NSIndexSet indexSetWithIndexesInRange:range];                                     
[self.tableView reloadSections:section withRowAnimation:UITableViewRowAnimationNone];

这将重新加载第一部分。我更喜欢在UITableView上有一个类别,只需调用此方法:

[self.tableView reloadSectionDU:0 withRowAnimation:UITableViewRowAnimationNone];

我的分类方法看起来像这样:

@implementation UITableView (DUExtensions)

- (void) reloadSectionDU:(NSInteger)section withRowAnimation:(UITableViewRowAnimation)rowAnimation {
    NSRange range = NSMakeRange(section, 1);
    NSIndexSet *sectionToReload = [NSIndexSet indexSetWithIndexesInRange:range];                                     
    [self reloadSections:sectionToReload withRowAnimation:rowAnimation];
}

1
喜欢 @implementation 函数!感谢你让它变得如此简单。 - benathon
使用 [NSIndexSet indexSetWithIndex:section] 调用不是更容易吗? - Frederic Yesid Peña Sánchez
5
你可以使用[NSIndexSet indexSetWithIndex:1]来替代range - Islam

37

是的,有这种情况:

- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation

27

但是你只能重新加载那些包含相同数量行的节(否则你需要手动添加或删除它们)。否则,你将会遇到以下错误:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 2. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (0), plus or minus the number of rows inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'

这种情况下,你可以使用[tableView reloadData],就不需要上述操作。

当你需要重新加载一个节,并且节内行数已更改时,你可以使用如下方法:

NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:section];

[self beginUpdates];
    [self deleteSections:indexSet withRowAnimation:rowAnimation];
    [self insertSections:indexSet withRowAnimation:rowAnimation];
[self endUpdates];

如果你把它放在一个类别下面(比如像bandejapaisa展示那样),它可能看起来是这样的:

- (void)reloadSection:(NSInteger)section withRowAnimation:(UITableViewRowAnimation)rowAnimation {
    NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:section];

    [self beginUpdates];
        [self deleteSections:indexSet withRowAnimation:rowAnimation];
        [self insertSections:indexSet withRowAnimation:rowAnimation];
    [self endUpdates];
}

那么在什么情况下呢?现在更好的方法可能是使用KVO(从而获得基于某些模型更改的自动UITableView重新加载的可能性)-或者如果您使用CoreData,则可能会对NSFetchResultsController感兴趣。 - Inza
我遇到了这个问题。我只是在重新加载实际部分之前重新加载有问题的部分。这解决了问题。 - Clement Prem
我的朋友,这帮了我很多! - Johan Albrectsen

21

适用于 Swift 3、4 和 5

let sectionToReload = 1
let indexSet: IndexSet = [sectionToReload]

self.tableView.reloadSections(indexSet, with: .automatic)

6

正确的方式是:

[self.tableView beginUpdates]; 
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];

4

根据这里接受的答案,我制作了一个函数,可以使用动画重新加载表格中的所有部分。这可能通过仅重新加载可见部分进行优化。

[self.tableView reloadData];
NSRange range = NSMakeRange(0, [self numberOfSectionsInTableView:self.tableView]);
NSIndexSet *sections = [NSIndexSet indexSetWithIndexesInRange:range];
[self.tableView reloadSections:sections withRowAnimation:UITableViewRowAnimationFade];

在我的情况下,在执行区域动画之前,我必须强制重新加载数据,因为表格的底层数据已更改。然而,它可以正确地进行动画处理。

2

您需要这个... 用于重新加载行

- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation

或重新加载部分
- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation

2
这是一个方法,您可以通过不同的方式传递部分详细信息。
[self.tableView reloadSections:[[NSIndexSet alloc] initWithIndex:1] withRowAnimation:NO];

[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:1] withRowAnimation:UITableViewRowAnimationNone];

重新加载特定的部分可以提高表格视图的性能,有时还可以避免一些问题,比如在视图中浮动/移动自定义标题-页脚。因此,请尽可能使用reloadSection而不是reloadData。


2

尝试使用

[self.tableView beginUpdates]; 
[self.tableView endUpdates];

希望这能解决你的问题。

1

但是你只能重新加载包含相同行数的部分(或者你必须手动添加或删除它们)。否则,你将会收到一个NSInternalInconsistencyException。

步骤:

  1. 计算要删除和/或插入的行
  2. 从这些生成IndexPath数组
  3. 调用相关的tableView方法

现在你可以安全地调用reloadSections :) 重新加载部分将调用其余索引的更新。

或者,你可以使用像这样的库:https://github.com/onmyway133/DeepDiff

Swift伪代码:


        tableView.deleteRows(at: valueIndexesToRemove, with: .automatic)
        tableView.insertRows(at: valueIndexesToInsert, with: .automatic)
        tableView.reloadSections(IndexSet([section]), with: .automatic)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接