UIScrollView原理

一、原理:

scrollView自带一个PanGesture滑动手势,滑动时修改scrollview的bounds.y,实现子视图有滑动效果。
参考:https://www.jianshu.com/p/964313cfbdaa

二、触摸事件打断

根据《事件传递 响应链》所知,自带的滑动手势会打断响应链中视图的touch方法,可以通过手势属性cancelsTouchesInView=NO ,让这个手势不打断响应者的touch方法。
参考:https://www.jianshu.com/p/b0884faae603

三、scrollView的一个机制

scrollView的属性delaysContentTouches 和 canCancelContentTouches控制事件响应交给scrollview子视图还是scrollView的手势。

从你的手指touch屏幕开始,scrollView开始一个timer,如果:

  • 150ms内如果你的手指没有任何动作,消息就会传给subView。
  • 150ms内手指有明显的滑动(一个swipe动作),scrollView就会滚动,消息不会传给subView。
  • 150ms内手指没有滑动,scrollView将消息传给subView,但是之后手指开始滑动,scrollView传送touchesCancelled消息给subView,然后开始滚动。
    delaysContentTouches:默认值为YES。如果设置为NO,则会立即把事件传递给subView。canCancelContentTouches:默认为YES,如果设置为NO,这消息一旦传递给subView,这scroll事件不会再发生。
    参考:https://www.jianshu.com/p/2b171f6153ad

四、scrollview和子视图事件冲突

canCancelContentTouches用来控制scrollview的全局冲突设置,以下两个scrollview方法用来分开控制scrollview与子视图事件冲突


下面这个函数的功能是判断是否可以把touch 事件传递给子视图,即在他上面的视图。当返回是yes 的时候就表示可以,就当点击子视图view 的时候停止响应scroll事件,改而响应子视图的touch 事件,当为no 时则拒绝子视图响应,执行父视图的touch 事件

//scrollview的delaysContentTouches=NO时,会立刻调用这个方法,看是否滚动scrollview,用来控制子视图是否响应touch事件
- (BOOL)touchesShouldBegin:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view{
}


用来具体控制某个scrollview子视图是否打断touch,不打断子视图touch意味着触摸在这个子视图时,scrollview不会滑动

当UIScrollView将touch事件交给子view后,当手指发生滑动时,调用此方法,假如返回NO,则将touch事件交给view,如果返回YES,则交给UIScrollView处理,产生滑动。(但是前提是UIScrollView的canCancelContentTouches属性是YES才会调用这个方法,只要不是UIControll的子类,这个属性默认是YES。)

- (BOOL)touchesShouldCancelInContentView:(UIView *)view{




return NO;不打断子视图touch,scrollview不滑动
return YES;打断子视图touch,scrollview滑动}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容