2009-09-24 71 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]; 
    } 
}