UIView的Touch事件

2016-08-12  本文已影响1596人  CoderRH

处理事件的方法

   //一根或者多根手指开始触摸view
   - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
   //一根或者多根手指在view上移动
   - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
   //一根或者多根手指离开view
   - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
   //触摸结束前,某个系统事件(例如电话呼入)会打断触摸过程
   - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event

UITouch对象

   //返回值表示触摸在view上的位置
   //这里返回的位置是针对view的坐标系的(以view的左上角为原点(0, 0))
   //调用时传入的view参数为nil的话,返回的是触摸点在UIWindow的位置
   - (CGPoint)locationInView:(UIView *)view;
   // 该方法记录了前一个触摸点的位置
   - (CGPoint)previousLocationInView:(UIView *)view;

UIEvent对象

每产生一个事件,就会产生一个UIEvent对象

   //事件类型
   //@property(nonatomic,readonly) UIEventType     type;
   //@property(nonatomic,readonly) UIEventSubtype  subtype;
   //事件产生的时间
   @property(nonatomic,readonly) NSTimeInterval  timestamp;
   UIEvent还提供了相应的方法可以获得在某个view上面的触摸对象(UITouch)

事件的产生和传递

如何找到最合适的控件来处理事件

注意点

响应者链

事件传递的完整过程

响应者链的事件传递过程

hitTest方法&pointInside方法

hitTest方法

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;

pointInside方法

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;

hitTest:withEvent:的实现原理

- (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] == NO) return nil;

    // 3.从后往前遍历自己的子控件
    NSInteger count = self.subviews.count;

    for (NSInteger 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) { // 寻找到最合适的view
            return fitView;
        }
    }
    // 循环结束,表示没有比自己更合适的view
    return self;
}
上一篇 下一篇

猜你喜欢

热点阅读