如何在不使用完成块的情况下在动画后执行代码?

How to execute code after an animation without using the completion block?

我想在内置动画完成后执行一些代码。

我有一个包含很多 cells/rows 的 UITableView。有时,当我进行一些操作时,我需要滚动到 tableView 的顶部。为此,我使用:

tableView.scrollToRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 0), atScrollPosition: UITableViewScrollPosition.Top, animated: true)

但是我需要在到达顶部后执行一些代码,例如第 1 行的简单 select 和 deselect。

我从 UIScrollViewDelegate 实现了 func scrollViewDidEndScrollingAnimation(scrollView: UIScrollView)。它工作正常(或多或少,有时动画不是很流畅,我们看不到 select/deselect "animation")除非我已经在 tableView 的顶部,然后 scrollViewDidEndScrollingAnimation 未被调用。

那么有没有办法在 scrollToRowAtIndexPath:atScrollPosition:animated 被调用后执行一些代码?

编辑:

当我说到做一些操作时,我说的是使用 moveRowAtIndexPath:toIndexPathUITableView 移动一行。

所以当需要滚动时没关系,两个动画花费的时间大致相同。但是当不需要滚动时,我想在动画之后执行的代码与动画同时开始

您可以使用我改编自 an old Objective-C answer 的 Swift 代码来滚动视图。

// First, test whether the tableView needs to scroll to the new position
var originalOffset = tableView.contentOffset.y;
tableView.scrollToRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 0), atScrollPosition: UITableViewScrollPosition.Top, animated: false)

var offset = tableView.contentOffset.y;

if (originalOffset == offset) {
    // No animation is needed since its already there
    doThingAfterAnimation();
} else {
    // We know it will scroll to a new position
    // Return to originalOffset. animated:NO is important
    tableView.setContentOffset(CGPointMake(0, originalOffset), animated: false);
    // Do the scroll with animation so `scrollViewDidEndScrollingAnimation:` will execute
    tableView.scrollToRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 0), atScrollPosition: UITableViewScrollPosition.Top, animated: true)
}

当然还有:

func scrollViewDidEndScrollingAnimation(scrollView: UIScrollView) {
    doThingAfterAnimation();
}