美文网首页iOS基础篇
iOS基础篇-事件处理

iOS基础篇-事件处理

作者: 麦子_KB | 来源:发表于2018-02-01 17:23 被阅读4次
    1、首先需要理解iOS事件处理机制

    理解事件处理、响应者、响应者链概念
    https://developer.apple.com/documentation/uikit/touches_presses_and_gestures/understanding_event_handling_responders_and_the_responder_chain

    当view超出其parentView边界时,响应事件的处理
    https://developer.apple.com/library/content/qa/qa2013/qa1812.html

    Responder chains in an app

    以上都是官方文档,建议认真研读!

    2、结合Demo讲解

    以下是我自己写得demo,测试验证响应者链事件传递。


    view layuot
    • TargetBtn layout 超出superView bounds(图中蓝色区域部分),当点击超出superView区域时,并不会触发TargetBtn的点击事件。
    • 在应对某些需求,如让TargetBtn超出superView也能响应点击事件,而又不改变layout。解决办法就是重写superView的
    - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
    

    Demo代码
    创建可重写点击事件的view:

    @interface WilsonView : UIView
    
    @property (weak, nonatomic) IBOutlet UIButton *targetBtn;
    
    @end
    
    @implementation WilsonView
    
    - (void)layoutSubviews {
        [super layoutSubviews];
        [self setColorTargetBtn];
    }
    
    - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
        
        // 将点击事件的点,从原有参考坐标系转换为目标视图的坐标系
        CGPoint pointForTargetView = [self.targetBtn convertPoint:point fromView:self];
        
        // 判断转换后的点是否位于目标视图中
        if (CGRectContainsPoint(self.targetBtn.bounds, pointForTargetView)) {
             // 返回目标视图
             // !!! 注意目标视图只能是当前view的直接子视图或者间接自视图 !!!
            return [self.targetBtn hitTest:pointForTargetView withEvent:event];
        }
        
        return [super hitTest:point withEvent:event];
    }
    
    #pragma mark - setSubviews
    
    - (void)setColorTargetBtn {
        self.targetBtn.layer.borderColor = [UIColor redColor].CGColor;
        self.targetBtn.layer.borderWidth = 1.0f;
    }
    
    @end
    

    在viewController中响应点击事件,验证结果:

    @interface ViewController ()
    
    @property (weak, nonatomic) IBOutlet UILabel *resultLab;
    
    @property (weak, nonatomic) IBOutlet UIButton *otherBtn;
    
    @property (weak, nonatomic) IBOutlet UIButton *topBtn;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        [self setColorTopBtn];
        [self setColorOtherBtn];
    }
    
    - (void)setColorTopBtn {
        self.topBtn.layer.borderColor = [UIColor grayColor].CGColor;
        self.topBtn.layer.borderWidth = 1.0f;
    }
    
    - (void)setColorOtherBtn {
        self.otherBtn.layer.borderColor = [UIColor blueColor].CGColor;
        self.otherBtn.layer.borderWidth = 1.0f;
    }
    
    #pragma mark - Action
    
    - (IBAction)click100Button:(id)sender {
        [self showText:@"target button"];
    }
    
    - (IBAction)clickTopButton:(UIButton *)sender {
        [self showText:@"top button"];
    }
    
    - (IBAction)clickOtherButton:(UIButton *)sender {
        [self showText:@"other button"];
    }
    
    - (void)showText:(NSString *)text {
        self.resultLab.text = text;
    }
    
    • 当点击topBtn区域时,并不会响应targetBtn事件,也不会执行superView的hitTest:方法,此时响应者链并没有将事件传递给superView,因此也不会传递到targetBtn;
    • 当点击除topBtn区域外的targetBtn区域时,会响应点击事件,我们重写hitTest:方法到达了目的。
    • 分析:当点击除topBtn区域外的targetBtn区域时,superView会判断点击point是否位于自身的bounds内,若在它的范围内,则会把事件传递给targetBtn;若不在它范围内,则事件不会继续传递到superView的子view。我们做的事情就是告诉superView,当点击区域在它的范围内时,找到她的子view或更深层的子view来响应事件。

    Demo地址:https://github.com/MrWilsonXu/HandleEvent.git

    相关文章

      网友评论

        本文标题:iOS基础篇-事件处理

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