2011-11-29 158 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)