如何检测animation已经结束UITableView beginUpdates / endUpdates?

我使用beginUpdates/endUpdatesbeginUpdates/endUpdates insertRowsAtIndexPaths/deleteRowsAtIndexPaths插入/删除表格单元格。 调整rowHeight时,我也使用beginUpdates/endUpdates 。 所有这些操作默认都是animation的。

如何使用beginUpdates/endUpdates检测animation是否已经结束?

那这个呢?

 [CATransaction begin]; [CATransaction setCompletionBlock:^{ // animation has finished }]; [tableView beginUpdates]; // do some work [tableView endUpdates]; [CATransaction commit]; 

这是有效的,因为tableViewanimation在内部使用CALayeranimation。 也就是说,他们将animation添加到任何开放的CATransaction 。 如果没有打开的CATransaction存在(正常情况下),则隐式地开始,在当前的runloop结束时结束。 但是如果你自己开始,就像在这里完成,那么它将使用那个。

Swift版本


 CATransaction.begin() CATransaction.setCompletionBlock({ do.something() }) tableView.beginUpdates() tableView.endUpdates() CATransaction.commit() 

一个可能的解决scheme可能是从您调用endUpdates的UITableViewinheritance并覆盖其setContentSizeMethod ,因为UITableView调整其内容大小以匹配添加或删除的行。 这种方法也适用于reloadData

为了确保只有在endUpdates之后才发送通知,还可以覆盖endUpdates并在那里设置一个标志。

 // somewhere in header @private BOOL endUpdatesWasCalled_; ------------------- // in implementation file - (void)endUpdates { [super endUpdates]; endUpdatesWasCalled_ = YES; } - (void)setContentSize:(CGSize)contentSize { [super setContentSize:contentSize]; if (endUpdatesWasCalled_) { [self notifyEndUpdatesFinished]; endUpdatesWasCalled_ = NO; } } 

你可以把你的操作放在UIViewanimation块中,如下所示:

 - (void)tableView:(UITableView *)tableView performOperation:(void(^)())operation completion:(void(^)(BOOL finished))completion { [UIView animateWithDuration:0.0 animations:^{ [tableView beginUpdates]; if (operation) operation(); [tableView endUpdates]; } completion:^(BOOL finished) { if (completion) completion(finished); }]; } 

致谢https://stackoverflow.com/a/12905114/634940

你可以使用tableView:willDisplayCell:forRowAtIndexPath: like:

 - (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { NSLog(@"tableView willDisplay Cell"); cell.backgroundColor = [UIColor colorWithWhite:((indexPath.row % 2) ? 0.25 : 0) alpha:0.70]; } 

但是,当已经在桌子上的单元格从屏幕上移到屏幕上时,这也会被调用,所以它可能不是你正在寻找的东西。 我只是查看了所有的UITableViewUIScrollView委托方法,并没有看到任何东西处理单元格插入animation后。


为什么不直接在endUpdates之后endUpdatesanimation结束时要调用的方法呢?

 - (void)setDownloadedImage:(NSMutableDictionary *)d { NSIndexPath *indexPath = (NSIndexPath *)[d objectForKey:@"IndexPath"]; [indexPathDelayed addObject:indexPath]; if (!([table isDragging] || [table isDecelerating])) { [table beginUpdates]; [table insertRowsAtIndexPaths:indexPathDelayed withRowAnimation:UITableViewRowAnimationFade]; [table endUpdates]; // --> Call Method Here <-- loadingView.hidden = YES; [indexPathDelayed removeAllObjects]; } } 

还没有find一个很好的解决scheme(短的UITableView子类)。 我已经决定使用performSelector:withObject:afterDelay:现在。 不理想,但完成工作。

更新 :它看起来像我可以使用scrollViewDidEndScrollingAnimation:为此(这是特定于我的实现,请参阅评论)。