美文网首页
02.2--iOS中的事件-触摸事件

02.2--iOS中的事件-触摸事件

作者: weyan | 来源:发表于2018-11-26 08:30 被阅读0次

    一、UIView的触摸事件

    • 创建一个红色的view继承UIView

    1、UIView的拖拽

    • 创建一个view,用手指拖拽该view在屏幕的不同位置
    #import "RedView.h"
    
    @implementation RedView
    
    //当开始触摸是自动调用
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        
        NSLog(@"%s",__func__);
    }
    
    //当触摸移动时调用
    //NSArray:集合里面存入的元素都是有序的
    //NSArray:集合里面存入的元素都是无序的
    - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
         NSLog(@"%s",__func__);
        
        //获取UITouch对象
        UITouch *touch = [touches anyObject];
        
        //上一个点:prePoint
        //当前点:curPoint
        //获取上一点
        CGPoint preP = [touch previousLocationInView:self];
        //获取当前点
        CGPoint cur = [touch locationInView:self];
      
        NSLog(@"preP = %@",NSStringFromCGPoint(preP));
        NSLog(@"cur = %@",NSStringFromCGPoint(cur));
    
        //x偏移量 = 当前点.x – 上一个点的.x
        CGFloat offsetX = cur.x - preP.x;
        //y偏移量 = 当前点.y – 上一个点的.y
        CGFloat offsetY = cur.y - preP.y;
    
        //让当前View跟着手指移动
        //Transform->平移
        self.transform = CGAffineTransformTranslate(self.transform, offsetX, offsetY);
    
    }
    
    //当手指离开时调用
    - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        NSLog(@"%s",__func__);
    }
    
    //当系统事件打断当前的触摸事件时调用
    - (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    }
    
    @end
    

    2、事件的产生和传递

    #import "WhiteView.h"
    
    @implementation WhiteView
    
    //5.找到后调用touchesBegan:方法
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        
        NSLog(@"%@----touch",[self class]);
    }
    
    //什么时候调用:当事件传递给当前View时, 会调用当前Veiw的hitTest方法.
    //作用:寻找最适合的View.
    //返回值:返回谁,谁就是最适合的view,谁就响应事件,就会调用谁的touches方法
    - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
        
        //1.判断自己能否接收事件
        //2.点在不在自己身上(通过调用下面的pointInside:方法)
        
        //3.从后往前遍历自己了的子控件,把事件传递给子控件,调用子控件的hitTest,
        //4.如果子控件没有找到最适合的View,那么自己就是最适合的View.
        return  [super hitTest:point withEvent:event];
        
    }
    
    
    //作用:点在不在自己身上,调用当前View一个方法(pointInside:)
    //什么时候调用:在hitTest内部调用的
    //返回值:YES在当前View身上, NO,不在
    //point:当前触摸点
    //注意:必须得要跟方法调用者在同一个坐标系
    - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
        return YES;
    }
    
    
    @end
    
    • hitTest方法内部实现
    #import "XMGWindow.h"
    
    @implementation XMGWindow
    
    - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
        //1.判断自己能否接收事件
        if (self.userInteractionEnabled == NO || self.hidden == YES || self.alpha <= 0.01) {
            //不能接收事件
            return nil;
        }
        //2.点在不在自己身上
        if (![self pointInside:point withEvent:event]) {
            return nil;
        }
        
        //3.从后往前遍历自己的子控件,把事件传递给子控件,调用子控件的hitTest,
        int count = (int)self.subviews.count;
        
        for (int i = count - 1; i >= 0; i--) {
            //获取子控件
            UIView *childView = self.subviews[i];
            
            //把当前点的坐标系转换成子控件的坐标系
            CGPoint childP = [self convertPoint:point toView:childView];
            
            UIView *fitView = [childView hitTest:childP withEvent:event];
            
            if (fitView) {
                return fitView;
            }
        }
        //4.如果子控件没有找到最适合的View,那么自己就是最适合的View.
        return self;
        
    }
    
    @end
    
    • 判断点是不是在一个view上
      image.png
    #import "YellorView.h"
    
    @interface YellorView ()
    @property (nonatomic,weak) IBOutlet UIButton *redBtn;
    @end
    
    @implementation YellorView
    
    - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
        
        //判断点在不在红色按钮身上, 如果在,直接返回红色按钮
        CGPoint redP = [self convertPoint:point toView:self.redBtn];
        
        if ([self.redBtn pointInside:redP withEvent:event]) {
            return self.redBtn;
        }
        //否则保持原有做法.
        return [super hitTest:point withEvent:event];
        
    }
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        
        NSLog(@"%s",__func__);
        
    }
    

    3、事件响应(响应者链条)

    相关文章

      网友评论

          本文标题:02.2--iOS中的事件-触摸事件

          本文链接:https://www.haomeiwen.com/subject/mrwqtqtx.html