检测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 } } }