iOS - 从 UITableView 中删除行没有动画

Posted

技术标签:

【中文标题】iOS - 从 UITableView 中删除行没有动画【英文标题】:iOS - deleting row from UITableView doesn't animate 【发布时间】:2013-08-22 13:47:37 【问题描述】:

我有一个非常令人沮丧的问题。我有一个带有 UITableView 的应用程序。 当我从表格视图中删除一个单元格时,它会从数据模型中删除,然后我调用以下命令:

-(void)removeItem:(NSIndexPath *)indexPath 
    [self.tableView beginUpdates];

    [self.tableView deleteRowsAtIndexPaths:@[indexPath]
                      withRowAnimation:UITableViewRowAnimationRight];
    [self.tableView endUpdates];

我的问题是,我已经像上面那样尝试过,并且我尝试过不使用 animateWithDuration。我什至尝试过使用 CATransaction,但无论我怎么做,动画都不会发生。

我的模拟器中有慢速动画,当我从列表中删除一个项目时,它会正确删除,但没有动画。 在重新加载表格视图数据之前,它会消失并留有片刻空白。

我在 SO 和 Google 上都进行了搜索,但似乎找不到答案。 有什么想法吗?

这可能与我在调用上述函数之前从数据模型中删除对象有关吗?

编辑:删除不正确的动画块

【问题讨论】:

尝试将其全部从 animateWithDuration:animations: 块中删除。表格视图自己处理动画,你不需要做任何其他事情。 请显示您的commitEditingStyle: 方法 谢谢大家,但就像我在问题中所说的那样,我也尝试不使用 animateWithDuration:animations: ,但它并没有解决问题。 @Valentin:很快就会出现。 我对这部分代码和一般的 ios 相当陌生。我看到我们没有实现 commitEditingStyle: 方法。从数据模型中实际删除发生在 RESTKit 调用中的删除块中,如果这有影响的话。 我建议从您的问题中编辑动画块,因为它完全是错误的。否则,您共享的代码看起来是正确的。但你并没有真正分享太多。我想知道你还在做什么可能会中断动画。您说“在重新加载表视图数据之前”。我不知道你的意思是什么。你打电话给reloadData不是因为这可能会破坏动画吗? 【参考方案1】:

根据THIS,您根本不需要使用animateWithDuration:animations:

就这样试试吧

-(void)removeItem:(NSIndexPath *)indexPath 
    [self.tableView beginUpdates];
    [self.tableView deleteRowsAtIndexPaths:@[indexPath]
                  withRowAnimation:UITableViewRowAnimationRight];
    [self.tableView endUpdates];

【讨论】:

谢谢大家,但就像我在问题中所说的那样,我也尝试不使用 animateWithDuration:animations: ,但它并没有解决问题。【参考方案2】:

好吧,我不知道这是否只是不礼貌,但我觉得我会在这里回答我自己的问题。

首先,感谢所有其他答案,当然你们都是正确的,但没有一个答案能解决我的问题。

事实证明,代码中的另一个区域进行了不同的检查,然后调用了其中一个 tableView 委托方法,这似乎取消了动画。

所以答案如下:

当您正在删除行但动画不起作用时,请确保在动画开始之前您没有调用 didSelectRowAtIndexPath:indexPath。这将取消动画。


如果你没有遇到这个问题,这里有一些非常典型的扩展代码,示例中有两行:

请注意,facebookRowsExpanded 是您必须拥有的类变量:

if ( [theCommand isEqualToString:@"fbexpander"] )

NSLog(@"expander button......");
[tableView deselectRowAtIndexPath:indexPath animated:NO];

NSArray *deleteIndexPaths;
NSArray *insertIndexPaths;

facebookRowsExpanded = !facebookRowsExpanded;
// you must do that BEFORE, not AFTER the animation:

if ( !facebookRowsExpanded ) // ie, it was just true, is now false
    
    deleteIndexPaths = [NSArray arrayWithObjects:
            [NSIndexPath indexPathForRow:2 inSection:0],
            [NSIndexPath indexPathForRow:3 inSection:0],
             nil];
    [tableView beginUpdates];
    [tableView
        deleteRowsAtIndexPaths:deleteIndexPaths
        withRowAnimation: UITableViewRowAnimationMiddle];
    [tableView endUpdates];
    
else
    
    insertIndexPaths = [NSArray arrayWithObjects:
            [NSIndexPath indexPathForRow:2 inSection:0],
            [NSIndexPath indexPathForRow:3 inSection:0],
             nil];
    [tableView beginUpdates];
    [tableView
        insertRowsAtIndexPaths:insertIndexPaths
        withRowAnimation: UITableViewRowAnimationMiddle];
    [tableView endUpdates];
    

// DO NOT do this at the end: [_superTableView reloadData];
return;

注意:numberOfRowsInSection 的代码必须使用 facebookRowsExpanded

(类似于“如果 facebookRowsExpanded 返回 7,否则返回 5”)

注意:cellForRowAtIndexPath 的代码必须使用 facebookRowsExpanded。

(它必须返回正确的行,取决于您是否展开。)

【讨论】:

我今天遇到了同样的问题,在我的情况下,结果证明调用 reloadData 方法会取消动画。通过删除 reloadData 方法带回了动画,我看到你还在代码末尾的注释中写了这个。【参考方案3】:

首先,您不需要自己为更改设置动画。

其次,我认为您需要在开始和结束更新之间对数据源进行更改。

您的方法应该如下所示:

-(void)removeItemAtIndexPath:(NSIndexPath *)indexPath

    [self.tableView beginUpdates];

    // I am assuming that you're just using a plain NSMutableArray to drive the data on the table.

    // Delete the object from the datasource.
    [self.dataArray removeObjectAtIndex:indexPath.row];

    // Tell the table what has changed.
    [self.tableView deleteRowsAtIndexPaths:@[indexPath]
                  withRowAnimation:UITableViewRowAnimationRight];

    [self.tableView endUpdates];

【讨论】:

我会看看这是否可能。从数据模型中移除是复杂的,并且完全发生在不同的地方,在一个与 RESTKit 调用耦合的块内。我会试一试,看看是否可行。我只是不知道这是否是问题所在。由于从 tableview 中删除是 100%,它只是没有动画。【参考方案4】:
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];
[self.tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];

indexPaths 是要在表中插入或删除的 NSIndexPaths 数组。

 NSarray *indexPaths = [[NSArray alloc] initWithObjects:
    [NSIndexPath indexPathForRow:0 inSection:0],
    [NSIndexPath indexPathForRow:1 inSection:0],
    [NSIndexPath indexPathForRow:2 inSection:0],
    nil];

【讨论】:

以上是关于iOS - 从 UITableView 中删除行没有动画的主要内容,如果未能解决你的问题,请参考以下文章

IOS 7:从分组样式 UITableView 的一部分中删除边框

iOS 从 UITableView 滑动以删除 plist 中的数组

如何在 Swift / iOS 中从 UITableView 中删除行并从 UserDefaults 中更新数组

从 Parse Array 中删除项目后 UITableView 崩溃

当我从单独的视图控制器中删除核心数据实体时,为啥会调用 UITableView 方法?

iOS UITableView删除组中唯一行,即[UITableView _endCellAnimationsWithContext:] warning