UIScrollView的事件响应原理

来源:互联网 发布:万网域名转让合同 编辑:程序博客网 时间:2024/06/08 17:11
UIScrollView的事件响应原理:

   (1)当多个视图进行叠加的时候,touch事件一般是作用到最上面的视图上;但是如果父视图是UIScrollView,并且touch子视图可能会造成父视图UIScrollView的滚动时 

           那么在手指触摸到UIScrollView的视图范围之内的一瞬间,会产生下面的动作:

           * 拦截触摸事件
           * 将UIScrollView的tracking属性变为YES
           * 一个内置的计时器开始生效,用来监控在极短的时间间隔内手指是否发生了移动

          > * case1:当检测到时间间隔内手指发生了移动,UIScrollView自己触发滚动,取消发送tracking 给子视图。tracking属性变为NO。手指触摸下即使有(可以响应触摸事件的)内部控件也不会再响应触摸事件。
          > * case2:当检测到时间间隔内手指没有移动,UIScrollView会发送tracking events到子视图上。tracking属性保持YES。手指触摸下如果有(可以响应触摸事件的)内部控件,则将触摸事件传递给相应控件进行处理。

  (2)UIScrollView的子控件要想接收touch事件,即用户点击UIScrollView上的子视图时,先处理子视图上的touch,而使UIScrollView不发生滚动。这时候就需要自定义UIScrollView,然后重载touchesShouldBegin:withEvent:inContentView:方法 ,从而决定该UIScrollView子视图是否接受touch事件。 

  (3)自定义UIscrollView的几个注意点

          (a). touchesShouldBegin:withEvent:inContentView 决定自己是否接收 touch 事件,YES:(自己不接收,发送事件)即不滚动;NO:(自己接收,不发送)即滚动;(PS:默认是YES)
          (b). touchesShouldCancelInContentView 开始发送 tracking messages 消息给 subview 的时候调用这个方法,决定是否发送 tracking messages 消息到subview。假如返回 NO,发送。YES 则不发送(PS:1和2配合使用)
          (c). scorllView的属性:delaysContentTouches 是个布尔值:
                    当 delaysContentTouches =  YES 时,用户触碰开始后,scroll view要延迟一会,看看是否用户有意图滚动。如果用户有滚动的意图,那么捕捉 touch-down 事件,否则就不捕捉。
                    当 delaysContentTouches = NO 时,用户触碰开始后,scroll view 会立即触发。 

核心代码:

 
//view是用户点击的视图
- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view
{
    // 获取一个UITouch
    UITouch *touch = [touches anyObject];
  
    // 获取当前的位置
    CGPoint current = [touch locationInView:self];
    CGFloat x = [UIScreen mainScreen].bounds.size.width;
    if (current.x >= x + 10) {
        //在子控件上,UIScrollView不接收触碰事件,发送事件
        return YES;
    else {
        return [super touchesShouldBegin:touches withEvent:event inContentView:view];
    }
}
 
 
- (BOOL)touchesShouldCancelInContentView:(UIView *)view
{  
    if ([view isKindOfClass:NSClassFromString(@"TapDetectingView")]) {
        return NO;
    else {
        return [super touchesShouldCancelInContentView:view];
    }
}

注意的问题

1. 如果storyboard中使用的是系统自带的MKMapView,则不需要自定义scrollView
2. 判断用户当前点击的视图时,点击BMKMapView对应的View类型是TapDetectingView,因此需要转换一下






0 0