iOS学习笔记iOS基本功

iOS事件响应

2019-08-10  本文已影响1人  鲲鹏DP
24CF98B1-83C5-4206-99B2-B9FFE552AF98.png

1.系统响应阶段

2.寻找最佳响应者

3.事件分发

找到最佳响应视图后,会调用最佳响应视图的touch相关方法,如果没有实现该方法,就会继承关系,逐一往上查找,如果某个祖先视图实现了,事件就交给它处理,一直没有找到,事件到了UIAapplication就会被抛弃;


代码分析


#import "BaseView.h"
#import <objc/message.h>
@implementation BaseView

+(void)load{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = [self class];
        
        Method   originMethod1 = class_getInstanceMethod(class, @selector(hitTest:withEvent:));
        Method   newMethod1 = class_getInstanceMethod(class, @selector(DKP_hitTest:withEvent:));
        BOOL didAddMethod1 = class_addMethod(class,  @selector(hitTest:withEvent:), method_getImplementation(newMethod1), method_getTypeEncoding(newMethod1));
        if (didAddMethod1) {
            class_replaceMethod(class, @selector(DKP_hitTest:withEvent:),method_getImplementation(originMethod1), method_getTypeEncoding(originMethod1));
        }else{
            method_exchangeImplementations(originMethod1, newMethod1);
        }
        
        Method   originMethod2 = class_getInstanceMethod(class, @selector(pointInside:withEvent:));
        Method   newMethod2 = class_getInstanceMethod(class, @selector(DKP_pointInside:withEvent:));
        BOOL didAddMethod2 = class_addMethod(class,  @selector(pointInside:withEvent:), method_getImplementation(newMethod2), method_getTypeEncoding(newMethod2));
        if (didAddMethod2) {
            class_replaceMethod(class, @selector(DKP_pointInside:withEvent:),method_getImplementation(originMethod2), method_getTypeEncoding(originMethod2));
        }else{
            method_exchangeImplementations(originMethod2, newMethod2);
        }
        
        
        Method   originMethod3 = class_getInstanceMethod(class, @selector(touchesBegan:withEvent:));
        Method   newMethod3 = class_getInstanceMethod(class, @selector(DKP_touchesBegan:withEvent:));
        BOOL didAddMethod3 = class_addMethod(class,  @selector(touchesBegan:withEvent:), method_getImplementation(newMethod3), method_getTypeEncoding(newMethod3));
        if (didAddMethod3) {
            class_replaceMethod(class, @selector(DKP_touchesBegan:withEvent:),method_getImplementation(originMethod3), method_getTypeEncoding(originMethod3));
        }else{
            method_exchangeImplementations(originMethod3, newMethod3);
        }
        
        
    });
}
-(UIView *)DKP_hitTest:(CGPoint)point withEvent:(UIEvent *)event{
    
    NSLog(@"%@------%s",NSStringFromClass([self class]),__func__);
    return [self DKP_hitTest:point withEvent:event];
}
-(BOOL)DKP_pointInside:(CGPoint)point withEvent:(UIEvent *)event{
    NSLog(@"%@------%s",NSStringFromClass([self class]),__func__);
    return  [self DKP_pointInside:point withEvent:event];
}
-(void)DKP_touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
     NSLog(@"%@------%s",NSStringFromClass([self class]),__func__);

}
B9021476-EE94-4904-994A-39757945C396.png

应用

扩大视图响应事件的范围,或则让指定视图响应事件

将上面的hitTest方法稍作修改,寻找最佳视图到了secondView时,return self,指定secodView为最佳响应者。

-(UIView *)DKP_hitTest:(CGPoint)point withEvent:(UIEvent *)event{
    
    NSLog(@"%@------%s",NSStringFromClass([self class]),__func__);
    if ([NSStringFromClass([self class]) isEqualToString:@"secondView"]) {
        return self;
    }
    return [self DKP_hitTest:point withEvent:event];
}

再来点击黄色的thirdView

6B2E45CB-F6EF-4427-B957-0B049A9DF315.png

结果:事件响应者链在secondView就中断了,scondView响应事件。


最后

上一篇 下一篇

猜你喜欢

热点阅读