UITouch事件处理过程详解

1.相关概念介绍:
1)iOS 中的事件类型有三种:触摸事件,加速计事件,远程控制事件.
2)响应者对象:只有继承自 UIResponder 类的对象才能接受并处理事件,这些对象成为 响应者对象.
例如: UIApplication UIViewController 以及 UIView 都继承自 UIResponder,都是响应者对象

3) UIResponder 内部提供了方法,处理不同类型的事件

2.处理事件的方法:
处理触摸事件:
1) -(void)touchesBegan: withEvent:
2) -(void)touchesMoved: withEvent:
3) -(void)touchesEnded: withEvent:
4) -(void)touchesCancelled: withEvent:
处理加速计事件:
1) -(void)motionBegan: withEvent:
2) -(void)motionEnded: withEvent:
3) -(void)motionCancelled: withEvent:
远程控制事件:
-(void)remoteControlReceivedWithEvent:

3.触摸事件的传递
1) 发生触摸事件后,系统会将该事件加入到一个由UIApplication管理的事件队列
2)UIApplication 单例对象会从事件队列中取出最前面的事件将其分发,最先分发的对象是程序的主窗口
3)主窗口调用 hitTest: withEvent: 方法在视图树中找到一个最合适的子视图来处理触摸事件,该子视图即为 hit-test视图

其中,在寻找处理事件的最合适控件的准则:
1) 判断自己是否能接受触摸事件,如果可以,则继续
2) 判断触摸点是否在自己身上,如果在,则继续
3) 从后往前遍历子控件,重复上面的两个步骤
4) 如果没有符合条件的子控件,那么自己最适合处理
5) 返回找到的最合适处理事件的控件

hitTest: 方法代码演示:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    NSLog(@"%@----hitTest:", [self class]);

    // 如果控件不允许与用户交互那么返回 nil
    if (self.userInteractionEnabled == NO || self.alpha <= 0.01 || self.hidden == YES) {
        return nil;
    }

    // 如果这个点不在当前控件中那么返回 nil
    if (![self pointInside:point withEvent:event]) {
        return nil;
    }

    // 从后向前遍历每一个子控件

    for (int i = (int)self.subviews.count - 1; i >= 0; i--) {
        // 获取一个子控件
        UIView *lastVw = self.subviews[i];
        // 把当前触摸点坐标转换为相对于子控件的触摸点坐标
        CGPoint subPoint = [self convertPoint:point toView:lastVw];
        // 判断是否在子控件中找到了更合适的子控件
        UIView *nextVw = [lastVw hitTest:subPoint withEvent:event];
        // 如果找到了返回
        if (nextVw) {
            return nextVw;
        }
    }

    // 如果以上都没有执行 return, 那么返回自己(表示子控件中没有"更合适"的了)
    return  self;
}

在 上面的方法中,是通过内部调用 - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event 方法来判断点是否在自己身上的

4.触摸事件的响应
在找到最合适处理触摸事件的控件后,调用控件的 touches方法来作具体的事件处理,后面就是事件响应的传递,具体传递过程可以参考 点我查看 中的事件处理原则部分内容.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值