【发布时间】:2012-01-08 13:24:07
【问题描述】:
我只想重新加载一个部分而不是整个表格。 UITableView有什么方法吗。
[tableView reloadData] 用于加载全表。
我想知道如何只加载一个部分,因为我的表中有大量行。
【问题讨论】:
-
调用 reloadData 仍然只会重新加载屏幕上的 UITableViewCells
标签: iphone uitableview
我只想重新加载一个部分而不是整个表格。 UITableView有什么方法吗。
[tableView reloadData] 用于加载全表。
我想知道如何只加载一个部分,因为我的表中有大量行。
【问题讨论】:
标签: iphone uitableview
是的,有:
- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation
【讨论】:
你需要这个...用于重新加载行
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
或用于重新加载部分
- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation
【讨论】:
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];
}
【讨论】:
[NSIndexSet indexSetWithIndex:1](而不是范围)
但您只能重新加载包含相同行数的部分 (或者您必须手动添加或删除它们)。否则你会得到:
*** 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];
}
【讨论】:
根据此处接受的答案,我制作了一个函数,该函数将使用动画重新加载表格中的所有部分。这可以通过仅重新加载可见部分来优化。
[self.tableView reloadData];
NSRange range = NSMakeRange(0, [self numberOfSectionsInTableView:self.tableView]);
NSIndexSet *sections = [NSIndexSet indexSetWithIndexesInRange:range];
[self.tableView reloadSections:sections withRowAnimation:UITableViewRowAnimationFade];
在我的例子中,我不得不在部分动画之前强制 reloadData,因为表的基础数据已经改变。但是它的动画效果很好。
【讨论】:
尝试使用
[self.tableView beginUpdates];
[self.tableView endUpdates];
希望这能解决您的问题。
【讨论】:
如果您有自定义剖面视图,您可以在视图控制器中添加对它的弱引用,并随时更新它。这是我的参考代码:
@property (weak, nonatomic) UILabel *tableHeaderLabel;
....
-(UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UITableViewHeaderFooterView *myHeader = [[UITableViewHeaderFooterView alloc] init];
UILabel *titleLabel = [[UILabel alloc] init];
[titleLabel setFrame:CGRectMake(20, 0, 280, 20)];
[titleLabel setTextAlignment:NSTextAlignmentRight];
[titleLabel setBackgroundColor:[UIColor clearColor]];
[titleLabel setFont:[UIFont systemFontOfSize:12]];
[myHeader addSubview:titleLabel];
self.tableHeaderLabel = titleLabel; //save reference so we can update the header later
return myHeader;
}
然后你可以像这样更新你的部分:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
self.tableHeaderLabel.text = [NSString stringWithFormat:@"Showing row: %ld", indexPath.row];
}
【讨论】:
正确的方法:
[self.tableView beginUpdates];
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
【讨论】:
这里是方法,你可以通过不同的方式传递section details
[self.tableView reloadSections:[[NSIndexSet alloc] initWithIndex:1] withRowAnimation:NO];
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:1] withRowAnimation:UITableViewRowAnimationNone];
重新加载特定部分可以提高表格视图的性能,有时它还可以避免一些问题,例如在视图中浮动/移动自定义页眉页脚。所以尽可能尝试使用 reloadSection 而不是 relaodData
【讨论】:
对于 Swift 3、4 和 5
let sectionToReload = 1
let indexSet: IndexSet = [sectionToReload]
self.tableView.reloadSections(indexSet, with: .automatic)
【讨论】:
但您只能重新加载包含相同行数的部分(或者您必须手动添加或删除它们)。否则你会得到一个 NSInternalInconsistencyException。
步骤:
现在您可以安全地调用 reloadSections :) Reload 部分将为其余索引调用更新。
或者您可以使用类似的库:https://github.com/onmyway133/DeepDiff
Swift 伪代码:
tableView.deleteRows(at: valueIndexesToRemove, with: .automatic)
tableView.insertRows(at: valueIndexesToInsert, with: .automatic)
tableView.reloadSections(IndexSet([section]), with: .automatic)
【讨论】: