美文网首页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基础篇-事件处理

    1、首先需要理解iOS事件处理机制 理解事件处理、响应者、响应者链概念https://developer.appl...

  • iOS 基础-02

    transform 事件 iOS中的事件可以分为3大类型 iOS中并不是所有的对象都能处理事件,只有基础于UIRe...

  • Runloop 简介

    Runloop 是 iOS 和 OSX 中和线程相关的基础概念。提供了线程循环处理事件的能力,当有事件处理时唤醒线...

  • iOS 事件以及手势的处理

    iOS 事件以及手势的处理 首先引用深入浅出iOS事件机制,iOS触摸事件处理详解,详解iOS触摸事件与手势识别三...

  • iOS 动画基础总结篇

    iOS 动画基础总结篇 iOS 动画基础总结篇

  • iOS Runloop 流程

    iOS Runloop 基础 我们runloop 的运行流程为 1. source0 代表触摸事件的处理 可以看到...

  • iOS基础补完计划--透过堆栈看事件响应机制

    iOS基础补完计划--透过堆栈看事件响应机制 iOS基础补完计划--透过堆栈看事件响应机制

  • UI部分-事件处理

    iOS事件处理- 用户使用App产生的事件及响应方法: iOS中不是任何对象都能处理事件,只有继承UIRespon...

  • iOS事件的响应者链

    iOS 事件响应者链 1 iOS中的事件 触摸事件 加速计事件 远程控制事件 在iOS中不是任何对象都能处理事件,...

  • React基础篇之事件处理

    概念

网友评论

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

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