iOS 之事件

作者: 追逐_chase | 来源:发表于2019-05-09 20:10 被阅读0次

    iOS的事件分类

    • 1 触摸事件(是开发中经常使用的事件)
      • 只有继承UIResponder的对象才能处理事件,对之做出响应,也称为响应者对象
      • UIApplication,UIView,UIViewController都是继承UIResponder,都可以处理事件
    • 2 加速计事件(摇一摇,跑步计数等)
    • 3 远程控制事件(耳机切换歌曲)

    触摸事件处理的的方法

    • 开始触摸

    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

    • 移动

    - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

    • 取消

    - (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

    • 结束

    - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

    UITouch触摸对象常用的方法和属性

    • 方法

    -1 - (CGPoint)locationInView:(nullable UIView *)view; 返回当前触摸对象的View的坐标点
    -2 - (CGPoint)previousLocationInView:(nullable UIView *)view;返回当前触摸View的上一次的触摸点

    • 属性
    @property(nonatomic,readonly) NSTimeInterval      timestamp;
    @property(nonatomic,readonly) UITouchPhase        phase;
    @property(nonatomic,readonly) NSUInteger          tapCount;   // touch down within a certain point within a certain amount of time
    @property(nonatomic,readonly) UITouchType         type
    

    demo例子(UIView的拖拽)

    给控制器,添加一个子控件UIView,在UIView中实现 触摸事件的处理方法

    
    - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
        //获取到UITouch对象
        UITouch *touch = [touches anyObject];
        //当前的触摸点
        CGPoint currentPoint = [touch locationInView:self];
        //获取到上一次移动的触摸点
        CGPoint prePoint = [touch previousLocationInView:self];
        //移动的差值
        CGFloat offsetX = currentPoint.x - prePoint.x;
        CGFloat offsetY = currentPoint.y - prePoint.y;
    
      //平移(transform), 在原来平移的基础上平移
        self.transform = CGAffineTransformTranslate(self.transform, offsetX, offsetY);
    
    }
    
    01_uiview的平移.gif

    事件的传递

    • 发生触摸事件之后,系统会将改事件加入到UIApplication管理的事件队列
    • UIApplication会从事件队列中取出最前面的事件,并将改事件分发给keyWindow处理
    • 主窗口(keyWindow)会在视图层中找到一个最合适的视图来处理这个事件
    • 当找到合适的View控件之后,就会调用触摸事件的touches方法 做出相应的事件处理

    注意: 事件的传递的一层一层的,从父控件传递给子控件,如果父控件不能接受事件的传递,那么子控件也就不能接受触摸事件

    02.png

    当点击绿色的View事件的传递过程为
    UIApplication ->UIWindow->粉色View->紫色View ->绿色View

    • 不能接受事件的3中情况
    //1.控件的属性,不可以交互的
    userInteractionEnabled = no
    
    //2.隐藏控件
    hidden = yes
    
    //3.透明度小于 0.01的控件
    
    //上述的3中情况,不可以处理事件
    
    

    寻找最合适的View处理事件

    操作判断

    • 1.判断是否可以处理事件
    • 2.触摸点是否在自己身上
    • 3.重后向前遍历,执行1,2的操作寻找子控件
    • 4.如果没有,则自己就是最合适的view

    需要实现的方法

    //一个事件传递给这个View的时候,这个方法就会被调用
    //返回的值,就是最合适的View
    - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
        
        return [super hitTest:point withEvent:event];
        
    }
    
    
    //判断当前点是不是在自己身上
    //当hitTest:withEvent:调用的时候,内部就会调用这个方法
    - (BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event{
        
        return YES;
    }
    
    

    hitTest: withEvent:方法的内部原理实现

    - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
        //内部实现方法
        
        //1.判断是否可以接受事件
        
        if (self.hidden == YES || self.alpha <= 0.01 || self.userInteractionEnabled == NO) {
            
            return nil;
        }
        
        //2.判断触摸点是否在自己身上
        if (![self pointInside:point withEvent:event]) {
            
            return nil;
        }
        
        //3.从后向前遍历子控件
    
        int count = (int)self.subviews.count;
        
        for (int i = count - 1; i >= 0; i--) {
            //获取到子控件
            UIView *chiledView = self.subviews[i];
            //转化坐标点 到子控件上
            CGPoint childPoint =  [self convertPoint:point toView:chiledView];
            //获取View
            UIView *fitView = [chiledView hitTest:childPoint withEvent:event];
            
            //如果存在,就是最合适的view
            if (fitView) {
                
                return fitView;
            }
        
        }
        
        
        //没有找到合适的View,返回自己
        return self;
        
    }
    
    

    注意:如果在判断的时候是 子控件 需要转化子控件的 坐标点

    相关文章

      网友评论

        本文标题:iOS 之事件

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