2012-12-10 78 views
11

我正在检测是否(不是何时)UIScrollView正在滚动。检测UIScrollView是否滚动

BOOL isScrolling = myscrollview.scrolling; 

我怎么会去实现呢?当使用setContentOffset:animated:时,.dragging.decelerating不适用。

+0

怎么样'scrollViewDidScroll'委托方法? – iDev

+0

只回答“何时”。 – Jonny

+1

有些复杂,但根据您需要这些信息的原因,您可以查看主运行循环的模式。例如,在没有滚动视图正在滚动或被拖动时,主运行循环可能会在'NSDefaultRunLoopMode'中。如果任何滚动视图正在滚动/被拖动,则它将处于不同的模式,即'NSRunLoopCommonModes'的一部分。例如,如果你想等待滚动来结束做某件事,你可以使用'CFRunLoopPerformBlock(CFRunLoopGetMain(),kCFRunLoopDefaultMode,block);' – Guillaume

回答

6

我通常通过在scrollViewWillBeginDragging:scrollViewDidEndDragging:willDecelerate:事件中设置一个布尔变量来做到这一点。

UIScrollView Docs

+0

我没有使用拖动...即使我想我仍然不会捕获setContentOffset:animated – Jonny

+1

您还可以实现'scrollViewDidEndScrollingAnimation:',当'setContentOffset:animated:'发起的动画结束时将调用... – Guillaume

+0

@Guillaume:我测试了它如果你使用动画,它就可以工作。你是否使用同时调用'setContentOffset'设置的属性?还是有另一种可能性来检查滚动何时开始?还有没有使用动画的可能性? – testing

12

这可能是做这件事的稍微狡猾的方式,但我已经在我的代码使用它之前,也没有让我失望呢。 :)

#import <QuartzCore/QuartzCore.h> 
--- 
BOOL isScrolling = [scrollView.layer animationForKey:@"bounds"] != nil; 

除了“self.contentOffset”一个UIScrollView的偏移存储在了UIView的“bounds.origin”属性,以及(我猜的,因为它是在较低的水平,更方便一点码)。当你调用[setContentOffset:animated:]时,它会把它作为CABasicAnimation传递给UIScrollView,操作“bounds”属性。

当然,如果scrollView本身的形状是动画,此检查也会返回true。在这种情况下,您可能需要将边界对象从动画中拉出([CAAnimation toValue])并进行手动比较,以查看“原点”本身是否完全改变。

这不是最优雅的解决方案,但我喜欢能够避免必须尽可能使用委托。特别是如果有问题的类是UIScrollView子类。 :)

+0

感谢您的回答TiM,您知道它是否通过了Apple的审核流程吗? – Randy

+1

不用担心兰迪!是的!它的确如此。它没有触及任何私人API。我已经在App Store中使用了这一行代码超过2年的应用程序。 :) – TiM

0
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView; 

使用标志来保存当前滚动状态? 它只能解决setContentOffset:animated:问题。 “滚动”只是一种效果,有很多方式可以使滚动视图“滚动”,例如,连续设置内容偏移。所以这个问题应该没有答案。

1

不是一个非常干净的解决方案..但应该是最可靠:

var isScrolling = false 

func scrollViewWillBeginDragging(_ scrollView: UIScrollView) { 
    isScrolling = true 
} 

func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { 
    if !decelerate { scrollViewDidEndScrolling(scrollView) } 
} 

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { 
    scrollViewDidEndScrolling(scrollView) 
} 

func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) { 
    scrollViewDidEndScrolling(scrollView) 
} 

func scrollViewDidEndScrolling(_ scrollView: UIScrollView) { 
    isScrolling = false 
}