UIScrollView的scrollRectToVisible:animated:方法,有没有一种方法可以在动画结束时调用一个方法?

13
有没有一种方法可以知道动画何时结束并且uiscrollview已经停止滚动。

关于这个非常古老的问题,现在有三种情况必须涵盖。这是iOS中最奇怪和最困难的问题之一。 :/ - Fattie
5个回答

21

1
它并不总是被调用,例如当scrollRectToVisible()在traitCollationDidChange中被调用时。 - Michał Ziobro
1
这是错误的,需要考虑三种不同的情况。 - Fattie
我同意@Fattie的评论,因为滚动可能有多种情况。这个答案不如下面Fattie的答案好。 - Michael
@Fattie 是的,出于某种原因 SO 机器人决定从我的声望中减去 1 点。无论如何,我只是想感谢你的回答。 - Michael

13

我这样做是因为有时对我来说使用委托并不实际,比如在UIViewController转换中进行此操作:

[UIView animateWithDuration:0.3 animations:^{
    [scrollView setContentOffset:CGPointMake(0, -scrollView.contentInset.top) animated:NO];
} completion:^(BOOL finished) {
    // This is called when it's complete
}];

没错!我也用了同样的代码,才达到了预期的效果。 - Developer
我把我的单元格修改代码放到了“完成”中,但是我的“动画”和“完成”正在逐行执行。不像预期的那样工作 :( - Bindiya
很遗憾,在许多情况下,这实际上会导致崩溃。 - Fattie

5

为您的UIScrollView实现UIScrollViewDelegate代理方法:

使用scrollViewDidEndScrollingAnimation:来检测滚动动画何时结束,当您通过调用setContentOffset:animated:scrollRectToVisible:animated:方法(使用animated:YES)启动滚动时。

如果您想要监控由触摸手势引起的滚动视图运动,请使用scrollViewDidEndDecelerating:方法,在滚动运动停止时调用。


对于任何在这里搜索的人,这个非常古老的答案现在是不正确的 - 谢谢,苹果!:/ - Fattie

3

你需要考虑三种情况。谢谢,苹果。

// do note that you need all three of the following

public func scrollViewDidEndScrollingAnimation(_ s: UIScrollView) {
    // covers case setContentOffset/scrollRectToVisible
    fingerOrProgrammaticMoveDone()
}

public func scrollViewDidEndDragging(_ s: UIScrollView, willDecelerate d: Bool) {
    if decelerate == false {
        // covers certain cases of user finger
        fingerOrProgrammaticMoveDone()
    }
}

public func scrollViewDidEndDecelerating(_ s: UIScrollView) {
    // covers certain cases of user finger
    fingerOrProgrammaticMoveDone()
}

在中间的那个语句里,要小心不要忘记额外的“if”从句。

然后在 fingerOrProgrammaticMoveDone() 中执行你需要的操作。

处理分页滚动的恶梦是一个很好的例子。非常非常难以知道你在哪一页。


-2

scrollViewDidEndDecelerating: 是 UIScrollView 的代理方法,当 scrollView 完全停止时会被调用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接