检测UIScrollView页面更改
有没有办法检测或获取通知时,用户更改页面启用分页启用UIScrollView?
实现UIScrollView的委托。 这种方法是你在找什么。
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
使用它来检测当前正在显示的页面,并在页面更改时执行一些操作:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView { static NSInteger previousPage = 0; CGFloat pageWidth = scrollView.frame.size.width; float fractionalPage = scrollView.contentOffset.x / pageWidth; NSInteger page = lround(fractionalPage); if (previousPage != page) { // Page has changed, do your thing! // ... // Finally, update previous page previousPage = page; } }
如果只有在滚动完全停止后才对页面更改做出反应,那么最好在scrollViewDidEndDecelerating:
delegate方法内而不是scrollViewDidScroll:
方法内执行上述操作。
在已启用分页的滚动视图中,您可以使用scrollViewDidEndDecelerating来了解视图在页面上的定位时间(可能是同一页面)。
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
scrollViewDidScroll
被调用的每一个动作。 在分页启用视图的情况下,可以用来查找何时滚动到下一页(如果在该点停止拖动)。
在谷歌页面检测的第一个结果,所以我不得不回答这个更好的解决scheme在我看来。 (即使这个问题是在两年半前问过的)。
我不想调用scrollViewDidScroll
来跟踪页码。 这对于那样简单的东西来说太过于夸张了。 使用scrollViewDidEndDecelerating
不会工作,并在页面更改停止但是 (这是一个很大但是)如果用户将在屏幕上滑动两次比正常快一点scrollViewDidEndDecelerating
将被调用一次。 您可以轻松地从第1页到第3页,而无需处理第2页。
这完全解决了我的:
- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView { scrollView.userInteractionEnabled = NO; } - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { //Run your code on the current page scrollView.userInteractionEnabled = YES; }
这样,用户一次只能刷一页,而没有上述风险。
如何结合UIScrollViewDelegate的两个方法?
在scrollViewDidEndDragging(_:willDecelerate:)
,如果它马上停止,我们做页面计算; 如果它正在减速,我们放开它,它将被scrollViewDidEndDecelerating(_:)
捕获。
代码用XCode版本7.1.1,Swift版本2.1进行testing
class ViewController: UIViewController, UIScrollViewDelegate { // MARK: UIScrollViewDelegate func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) { if decelerate == false { let currentPage = scrollView.currentPage // Do something with your page update print("scrollViewDidEndDragging: \(currentPage)") } } func scrollViewDidEndDecelerating(scrollView: UIScrollView) { let currentPage = scrollView.currentPage // Do something with your page update print("scrollViewDidEndDecelerating: \(currentPage)") } } extension UIScrollView { var currentPage: Int { return Int((self.contentOffset.x+ (0.5*self.frame.size.width))/self.frame.width)+1 } }
这是快速的解决scheme。
在要实现代码的类中创build两个属性currentPage和previousPage,并将它们初始化为0。
现在从scrollViewDidEndDragging( :willDecelerate :)和scrollViewDidEndDecelerating( :scrollView :)更新currentPage。
然后在scrollViewDidEndScrollingAnimation(_:scrollView :)中更新previousPage
//Class Properties var currentPage = 0 var previousPage = 0 func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) { updatePage(scrollView) return } func scrollViewDidEndDecelerating(scrollView: UIScrollView){ updatePage(scrollView) return } func updatePage(scrollView: UIScrollView) { let pageWidth:CGFloat = scrollView.frame.width let current:CGFloat = floor((scrollView.contentOffset.x-pageWidth/2)/pageWidth)+1 currentPage = Int(current) if currentPage == 0 { // DO SOMETHING } else if currentPage == 1{ // DO SOMETHING } } func scrollViewDidEndScrollingAnimation(scrollView: UIScrollView) { if previousPage != currentPage { previousPage = currentPage if currentPage == 0 { //DO SOMETHING }else if currentPage == 1 { // DO SOMETHING } } }