iOS入门-22事件响应链

概述

无论是在iOS还是在Android等以触屏为输入硬件的系统中,事件响应链都是很重要的,且设计的思想都是一样的。

一次触碰屏幕事件从外层向内层传递,从内层向外层响应。(隧道式传递,冒泡式响应)
iOS中事件传递AppDelegate -> UIWindow -> UIViewController -> 父UIView ->子UIView -> …

示例

我们自己新建自己的UIWindow,UIViewController,父UIView,子UIView用来演示响应顺序。涉及添加自己UIWindow请参看“iOS的UI-04-UIWindow”。
先看一下示例工程的目录
在这里插入图片描述

然后是各个文件的代码

需要仔细看各个情况下的log,来帮助理解事件传递和相应过程。

AppDelegate.h
#import <UIKit/UIKit.h>
//引入自定义window
#import "MYUIWindow.h"

@interface AppDelegate : UIResponder <UIApplicationDelegate>
//window属性
@property(retain,nonatomic) MYUIWindow* window;

@end
AppDelegate.m
#import "AppDelegate.h"
//引入自定义的window和viewcontroller
#import "MYUIWindow.h"
#import "MYViewController.h"

@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    
    //初始化自定义window
    self.window = [[MYUIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    //设置根视图控制器为我们自定义的视图控制器
    self.window.rootViewController = [MYViewController new];
    //给window设置个颜色,好区分个区域
    self.window.backgroundColor = [UIColor blueColor];
    //将自定义window添加并生效
    [self.window makeKeyAndVisible];
    
    return YES;
}

//点击屏幕回调
-(void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    //打印一下是否响应了事件,并打印下一个事件接受者
    NSLog(@"AppDelegate 事件响应! next==%@",self.nextResponder);
    //将事件传递给上级
    [super touchesBegan:touches withEvent:event];
}
@end
MYUIWindow.m(头文件未做处理这里就不贴了)
#import "MYUIWindow.h"

@implementation MYUIWindow

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/

-(void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    NSLog(@"MYUIWindow 事件响应! next==%@",self.nextResponder);
    [super touchesBegan:touches withEvent:event];
}

@end
MYViewController.h
#import <UIKit/UIKit.h>
//引入俩个自定义view
#import "ParentView.h"
#import "ChildView.h"

NS_ASSUME_NONNULL_BEGIN

@interface MYViewController : UIViewController
{
    //声明一下
    ParentView* _pv;
    ChildView* _cv;
}
@end
NS_ASSUME_NONNULL_END
MYViewController.m
#import "MYViewController.h"

@interface MYViewController ()

@end

@implementation MYViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    //将两个自定义view添加到屏幕上
    //为了区分个自的区域,设置view的大小和背景色
    _pv = [ParentView new];
    _pv.frame = CGRectMake(40, 40, 400, 500);
    _pv.backgroundColor = [UIColor orangeColor];
    
    _cv = [ChildView new];
    _cv.frame = CGRectMake(60, 60, 200, 300);
    _cv.backgroundColor = [UIColor redColor];
    
    [_pv addSubview:_cv];
    [self.view addSubview:_pv];
}

-(void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    NSLog(@"MYViewController 事件响应! next==%@",self.nextResponder);
    [super touchesBegan:touches withEvent:event];
}

@end
ParentView.m(头文件未做处理这里就不贴了)
#import "ParentView.h"
@implementation ParentView
-(void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    NSLog(@"ParentView 事件响应! next==%@",self.nextResponder);
    [super touchesBegan:touches withEvent:event];
}
@end
ChildView(头文件未做处理这里就不贴了)
#import "ChildView.h"

@implementation ChildView

-(void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    NSLog(@"ChildView 事件响应! next==%@",self.nextResponder);
    [super touchesBegan:touches withEvent:event];
}

@end

注意:

仔细看代码中注释,很简单;
如果将各个类中的touchesBegan回调函数去掉,看会有什么样的结果;
将[super touchesBegan:touches withEvent:event]去掉会有什么结果;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值