2009-09-24 42 views
32

我希望我的UITableView的行爲與聯繫人編輯器中的表格類似,即用戶應點擊編輯,並在每個部分的底部顯示「添加新類別」行。在UITableView中使用插入行

我使用下面的代碼來做到這一點,但問題是沒有平滑的過渡,因爲有聯繫人。相反,新的行突然出現。我如何獲得動畫?

另外,如何響應點擊「添加新類別」行?該行在我當前的實現中不可點擊。

用戶開始編輯時是否需要重新加載數據?我這樣做是因爲否則插入行從不繪製。

謝謝。

- (void)setEditing:(BOOL)editing animated:(BOOL)animated { 
    [super setEditing:editing animated:animated]; 
    [self.tableView setEditing:editing animated:animated]; 
    [tableView reloadData]; 
} 

- (NSInteger)tableView:(UITableView *)_tableView numberOfRowsInSection:(NSInteger)section { 
    // ... 
    if(self.tableView.editing) 
     return 1 + rowCount; 
} 

- (UITableViewCell *)tableView:(UITableView *)_tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    // ..... 
    NSArray* items = ...; 
    if(indexPath.row >= [items count]) { 
     cell.textLabel.text = @"add new category"; 
    } 
    // ... 

    return cell; 
} 

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { 
    NSArray* items = ...; 

    if(indexPath.row == [items count]) 
     return UITableViewCellEditingStyleInsert; 

    return UITableViewCellEditingStyleDelete; 
} 
+2

這是非常有益的(有答案一起,下同)。只是一個小的不一致性 - 與'tableView:cellForRowAtIndexPath:'中的行數比較'使用'> ='而'tableView:editingStyleForRowAtIndexPath:'中的使用'=='。沒什麼大不了的,但是它們之間應該是一致的。 '> ='將覆蓋任何意外的雙重添加插入行,而'=='將通過拋出一個異常來解決任何可能導致這種情況的代碼錯誤。 – 2013-01-21 20:38:15

回答

36

我錯過了一件事。在setEditing:,而不是調用reloadData我應該做的:

- (void)setEditing:(BOOL)editing animated:(BOOL)animated { 
    [super setEditing:editing animated:animated]; 
    [self.tableView setEditing:editing animated:animated]; // not needed if super is a UITableViewController 

    NSMutableArray* paths = [[NSMutableArray alloc] init]; 

    // fill paths of insertion rows here 

    if(editing) 
     [self.tableView insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationBottom]; 
    else 
     [self.tableView deleteRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationBottom]; 

    [paths release]; 
} 
+3

謝謝比爾,這對我非常有用。我用相似的代碼花了好幾個小時的時間,但不能完全正確。這非常有幫助。 – hkatz 2011-01-22 16:41:08

+0

很高興幫助! – Bill 2011-01-22 18:07:51

+0

commitEditingStyle:forRowAtIndexPath呢? Apple文檔說當表視圖第一次進入編輯模式時會調用setEditing ...您怎麼知道在那一點插入/刪除哪些行? – shim 2013-12-15 06:20:15

5

響應點擊該行可能會在didSelectRowAtIndexPath方法來完成,indexPath.row == [items count]。對於動畫,我建議看看here,在insertRowsAtIndexPaths:withRowAnimation:方法。有一篇關於如何使用它的文章here

0

突出顯示解決方案的不必要的副作用是,「添加」行也被插入時,用戶只需刷卡一個單行(前提是刷卡已啓用)。下面的代碼解決了這個難題:

// Assuming swipeMode is a BOOL property in the class extension. 

- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    // Invoked only when swiping, not when pressing the Edit button. 
    self.swipeMode = YES; 
} 

- (void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    self.swipeMode = NO; 
} 

您的代碼將需要一個小的變化:

- (void)setEditing:(BOOL)editing animated:(BOOL)animated { 
    [super setEditing:editing animated:animated]; 
    [self.tableView setEditing:editing animated:animated]; // not needed if super is a UITableViewController 

    if (!self.swipeMode) { 

     NSMutableArray* paths = [[NSMutableArray alloc] init]; 

     // fill paths of insertion rows here 

     if(editing) 
      [self.tableView insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationBottom]; 
     else 
      [self.tableView deleteRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationBottom]; 
     [paths release]; 
    } 
}