今天在做一个控件的动画,动画需求是这样的,当UICollectionView滚动开始和滚动结束的时候,一个底部控件需要做淡出淡入的效果。
在iOS中使用UIScrollView的子类的时候,需要知道UIScrollView滚动动画是否结束,一般我们都是通过UIScrollViewDelegate中去寻找方法。
1 | - (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView |
第一眼就相中它了,在我使用的过程中发现,在拖拽UIScrollView之后动画停止的时候,这个函数根本不会触发。翻看了apple给出的文档
The scroll view calls this method at the end of its implementations of
the setContentOffset:animated: and scrollRectToVisible:animated:
methods, but only if animations are requested.
文档中说明该函数只作用于 setContentOffset:animated: 和 scrollRectToVisible:animated: 这两个函数,调用时机是动画结束之后,并且只有当animated为YES的时候。后来查了一些资料发现还有一些函数也是会被调用的。归纳有以下几个
// UIScrollView的setContentOffset:animated:
// UIScrollView的scrollRectToVisible:animated:
// UITableView的scrollToRowAtIndexPath:atScrollPosition:animated:
// UITableView的selectRowAtIndexPath:animated:scrollPosition:
接下来我又找了下面这个函数,看上去挺像我们要找的
1 | - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView |
从实验来看,可以到达效果,但是有个bug出现了,这个函数有点不靠谱,不是一个自然停止会调用的,在手势中断动画滚动的时候也会调用。
之后在stackoverFlow上面找到了答案How to detect when a UIScrollView has finished scrolling
1 | -(void)scrollViewDidScroll:(UIScrollView *)sender |
上面的方法用的相当巧妙,至于原理就不解释了。