在 UITableView 中使用插入行

Posted

技术标签:

【中文标题】在 UITableView 中使用插入行【英文标题】:Using insert rows in a UITableView 【发布时间】:2010-12-01 01:13:08 【问题描述】:

我希望我的 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;

【问题讨论】:

这非常有帮助(连同下面的答案)。只有一点点不一致——与tableView:cellForRowAtIndexPath: 中的行数比较使用>=,而tableView:editingStyleForRowAtIndexPath: 中的行数使用==。没什么大不了的,但它们之间应该保持一致。 >= 将涵盖插入行的任何意外双重添加,而 == 将通过为可能导致这种情况的任何代码错误抛出异常来提供帮助。 【参考方案1】:

响应对行的点击可以在didSelectRowAtIndexPath 方法中完成,对于indexPath.row == [items count]。对于动画,我建议看一下here,insertRowsAtIndexPaths:withRowAnimation: 方法。有一个关于如何使用它的帖子here。

【讨论】:

【参考方案2】:

我错过了一件事。在 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];

【讨论】:

谢谢比尔,这对我很有用。我花了几个小时在类似的代码中胡思乱想,但无法完全正确。这带来了不可估量的帮助。 那么 commitEditingStyle: forRowAtIndexPath 呢? Apple 文档说 setEditing 在表格视图第一次进入编辑模式时被调用......你怎么知道此时要插入/删除哪些行? 我不明白你的问题 我认为在滑动单行时会调用 -setEditing:animated: 方法。在这种情况下,您不想插入带有“+”按钮的行。 (也许这就是 shim 的意思?)【参考方案3】:

突出显示的解决方案的一个不良副作用是,当用户只滑动一行时,也会插入“添加”行(前提是启用了滑动)。下面的代码解决了这个难题:

// 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];
    

【讨论】:

以上是关于在 UITableView 中使用插入行的主要内容,如果未能解决你的问题,请参考以下文章

在 UITableView 中使用插入行

iOS 9 UITableView分隔符插入(显着的左边距)

在 UITableView 中插入一些行后,它在 ios 7 中没有滚动

使用“插入”行初始化 UITableView

UITableView 中同时插入/删除行的问题

在uitableview中插入行并重新加载