作为进入编辑模式的一部分,在UITableView顶部插入新行时编辑样式的问题

时间:2009-10-02 06:53:41

标签: iphone uitableview

我有UITableView一个部分和'n'行(填充NSMutableArraymyTableArray)。进入编辑模式时,我想实现以下目标:

  • 设置“n”行以具有UITableViewCellEditingStyleDelete编辑样式
  • 在原始“n”上方插入一个新行,并将其设置为具有UITableViewCellEditingStyleInsert编辑样式

我的UITableViewController子类实现如下:

- (void)setEditing:(BOOL)flag animated:(BOOL)animated
{
    [super setEditing:flag animated:animated];

    UITableView *tableView = (UITableView *)self.view;
    NSArray *topIndexPath = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:0]];

    if (self.editing == YES)
        [tableView insertRowsAtIndexPaths:topIndexPath withRowAnimation:UITableViewRowAnimationBottom];
    else
        [tableView deleteRowsAtIndexPaths:topIndexPath withRowAnimation:UITableViewRowAnimationBottom];
}

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row == 0)
        return UITableViewCellEditingStyleInsert;
    else
        return UITableViewCellEditingStyleDelete;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (self.editing == YES)
        return [myTableArray count] + 1;
    else
        return [myTableArray count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // ... boiler-plate dequeueReusableCellWithIdentifier code, etc ...

    if (self.editing == YES)
    {
        if (indexPath.row == 0)
            cell.textLabel.text = @"My new row";
        else
            cell.textLabel.text = [myTableArray objectAtIndex:(indexPath.row - 1)];
    }
    else
    {
        cell.textLabel.text = [myTableArray objectAtIndex:indexPath.row];
    }

    return cell;
}

运行此代码并按下“编辑”按钮时,会在原始“n”行上方插入一个新行,但是,第二行除了第一行外,还具有UITableViewCellEditingStyleInsert编辑样式。例如,如果'n'为3,则在按下编辑按钮后,表格将显示:

  • 第0行:插入编辑样式
  • 第1行:插入编辑样式(应删除)
  • 第2行:删除编辑样式
  • 第3行:删除编辑样式

经过进一步调查后,我注意到如果'n'为3且按下了编辑按钮,方法tableView:editingStyleForRowAtIndexPath:总共被调用了8次:

  • [super setEditing:flag animated:animated]会对每个原始行0,1和2
  • 产生3次调用
  • 后续的[tableView insertRowsAtIndexPaths:topIndexPath withRowAnimation:UITableViewRowAnimationBottom]导致5次调用0,1,2,3行再次0

我可以理解编辑样式需要在插入新行时重新校正,但是我不明白为什么在最后5次调用中,第0行设置了两次,为什么第1行仍然设法有不正确的风格。

有没有人有任何见解?

2 个答案:

答案 0 :(得分:6)

我知道已经过了一年,但我用Google搜索并偶然发现了这一点,所以让我们为后人回答这个问题。

以下似乎有效。 TableViewController在有机会知道在顶部插入行之前询问编辑样式。所以我们应该跟踪我们是否在改变编辑模式和插入之间。

- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
    automaticEditControlsDidShow = NO;
    [super setEditing:editing animated:animated];
    NSArray *addRow = [NSArray arrayWithObjects:[NSIndexPath indexPathForRow:0 inSection:0],nil];
    if (editing) {
        automaticEditControlsDidShow = YES;
        [self.tableView insertRowsAtIndexPaths:addRow withRowAnimation:UITableViewRowAnimationLeft];
    } else {
        [self.tableView deleteRowsAtIndexPaths:addRow withRowAnimation:UITableViewRowAnimationLeft];
    }
}

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
    int row = indexPath.row;

    if (self.editing && row == 0) {
        if (automaticEditControlsDidShow)
            return UITableViewCellEditingStyleInsert;
        return UITableViewCellEditingStyleDelete;
    }
    return UITableViewCellEditingStyleDelete;
}

答案 1 :(得分:0)

尝试关闭插入的动画并查看调用内容的次数。

你在这里遇到的问题是当行0是现有的预插入行时调用super,然后你正在使用动画进行插入,这导致调用editingStyle ..方法。 / p>

以下建议很可怕,但您也可以尝试在调用super之前进行编辑的测试,并执行行插入/删除和THEN调用super。这样就有适当的行数。

更大的问题是......你确定你想让插入行成为最重要的一行吗?这是一个非标准的地方,除非你有一个很好的理由去违反UI准则,你可能要考虑重新设计你的UI以将插入样式的行放在底部....