2011-11-29 115 views
34

我想只重新加载一个部分而不是整个表。 UITableView有什么方法吗?UITableView重新加载部分

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

+2

调用reloadData仍然只有最初将重新加载上的屏幕 –

+0

可能重复的UITableViewCells http://stackoverflow.com/问题/ 3485162 /重新加载只有一个可用的viewcell-on-a-uitableview –

+0

thanx steve jobs for ur help –

回答

30

是的,有:

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

你需要这个......对于刷新行

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

或为重新加载部分

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

的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功能!感谢使它变得如此简单 – portforwardpodcast

+0

我无法得到这个工作。 – Jason

+0

@Jason你以前是否创建过自己的类别?另外,你有没有投票? – bandejapaisa

21

但是你可以重新加载仅含有相同数量的行的部分(或者你必须手动添加或删除它们)。否则,你将获得:

*** 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]; 
} 
+0

不幸的是,这并不适用于我。 –

+0

而在这种情况下?现在更好的方法可能是使用KVO(并因此基于对某些模型的更改而获得自动UITableView重载的可能性) - 或者如果您使用CoreData,则可能对NSFetchResultsController感兴趣。 – Inza

4

基于这里接受的答案,我做了一个函数,将使用动画重新加载表中的所有部分。这可能可以通过重新加载仅可见部分来优化。

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

在我的情况下,我不得不在部分动画之前强制reloadData,因为表的底层数据已经改变。然而它正确地动画。

2

尝试使用

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

希望这将解决您的问题。

0

如果您有自定义截面视图,您可以在视图控制器中为其添加弱引用,并在需要时进行更新。这里是我的参考代码:

@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]; 
} 
6

正确的方法:

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

这里是方法,你可以通过不同的方式传递部分细节

[self.tableView reloadSections:[[NSIndexSet alloc] initWithIndex:1] withRowAnimation:NO]; 

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

重新加载特定的部分可以提高表视图的性能,同时还可以避免在视图中浮动/移动自定义页眉页脚等问题。所以尽量使用reloadSection比relaodData尽可能

6

对于斯威夫特3和斯威夫特4

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

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