如何检测animation已经结束UITableView beginUpdates / endUpdates?
我使用beginUpdates/endUpdates
中beginUpdates/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在内部使用CALayer
animation。 也就是说,他们将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); }]; }
你可以使用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]; }
但是,当已经在桌子上的单元格从屏幕上移到屏幕上时,这也会被调用,所以它可能不是你正在寻找的东西。 我只是查看了所有的UITableView
和UIScrollView
委托方法,并没有看到任何东西处理单元格插入animation后。
为什么不直接在endUpdates
之后endUpdates
animation结束时要调用的方法呢?
- (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:
为此(这是特定于我的实现,请参阅评论)。