• iOS 事件响应者链的学习(也有叫 UI连锁链)


    当发生事件响应的时候,必须知道由谁来响应事件.在iOS中,由响应链来对事件进行响应,所有的事件响应的类都是继承于UIResponder的子类,响应链是一个由不同对象组成的层次结构,其中每个对象将依次获得响应事件消息的机会

    发生触摸事件后,系统将事件加入到由UIApplication管理的事件 队列 

    好处:遵循第一响应原则,总会优先处理队列中排在最前面的事件.(栈是先进后出 不符合业务逻辑)

    (1)事件传递(链)

    1.传递链中时没有controller的,因为controller本身不具有大小的概念

    2.用户的触摸事件首先会由系统截获,进行包装处理等。然后递归遍历所有的view,进行碰触测试(hitTest),直到找到可以处理事件的view

    大致的过程application –> window –> root view –>……–>lowest view 

    网上一个很直观的解释图

     

    (2)响应链

    1.响应链中是有controller的,因为controller继承自UIResponder

    2.当有view能够处理触摸事件后,开始响应事件。

            系统会调用view的以下方法:

            - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;

            - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;

            - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;

            - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;

            可以多对象共同响应事件。只需要在以上方法重载中调用super的方法。

            大致的过程initial view –> super view –> …..–> view controller –> window –> Application

    我记得 前年被一位CTO面试的时候 问到过这个问题 ,原话大概是说”触发一个按钮,怎么截获 它的触发消息”;当时说得一塌糊涂 ,但是由于 有个创意性的问题分析回答得特别到位 ,还夸奖了我,说我有想法,他还感冒了,说要去擤鼻子 然后就没在回来 .比较遗憾的面试,其实不要估计我是女生呀,我不怕拒绝,也没说原因呢,就没有然后了.

    现在想起来,估计这个”事件传递响应者链”的原理真的很重要,如今学习的更加深入,自然而然就会去讨论学习,在开发中运用起来. 真是成长如蜕啊.

    举例:

    其实开发中,真的好多地方可以运用到这个方法,用来截获一些信息啦,处理消息,获取对象,修改响应,或者具体知道自己实现一个方法到底该是怎样一个流程等.

    需求:在cell上添加一个按钮,点击一下进入下一个导航页面.

    之前通常的做法是,”  [cell.btn addTarget:  blabla ]” 写在视图控制器里面 ,因为这样很好的调用到viewController.

    现在知道了事件响应者链的原理  就利用这个机制解决一下吧

    2.1首先创建一个UIView 类别 扩展 一个实例方法 根据"事件响应者链原理" :判读UIView上的点击事件,如果已经传递到了UIViewController,则就进行处理。获取这个视图控制器.

    //
    //  UIView+EventLink.h
    //  TableViewDemo
    //
    //  Created by HF on 16/2/26.
    //  Copyright © 2016年 HF-zhjh. All rights reserved.
    //
    #import <UIKit/UIKit.h>
    @interface UIView (EventLink)
    -(UIViewController *)viewController;
    @end
    
    //
    //  UIView+EventLink.m
    //  TableViewDemo
    //
    //  Created by HF on 16/2/26.
    //  Copyright © 2016年 HF-zhjh. All rights reserved.
    //
    
    #import "UIView+EventLink.h"
    @implementation UIView (EventLink)
    //为UIView扩展一个方法,用于响应事件链
    -(UIViewController *)viewController{
        UIResponder *nexRes=[self nextResponder];                                                      
        do {
            //判读当前的响应者是否UIViewController
            if ([nexRes isKindOfClass:[UIViewController class]]) {
                //是否直接处理
                return  (UIViewController*)nexRes;
            }else{
                //否则继续寻找
                nexRes=[nexRes nextResponder];                                                  
            }
        } while (nexRes!=nil);
        return nil;
    }
    @end

    通过为UIView扩展一个分类(类别)方法之后,我们就可以在Cell中调用分类方法(viewController)处理事件响应了。

    //按钮事件
    //UITableViewCell 继承于UIView 所以 现在 cell 多了一个属性 就是 viewController 可以直接用了
    //其实还算是很方便 可读性也很高
    -(void)buttonAction:(UIButton *)btn{ //使用事件响应者 UIViewController *view=[[UIViewController alloc] init]; [self.viewController.navigationController pushViewController:view animated:YES]; [view release]; }

     (3)几种无法接受触摸事件的情况

    1.不接收用户交互

    userInteractionEnabled = NO

    2.隐藏
    hidden = YES

    3.透明
    alpha = 0.0 ~ 0.01

    提示:UIImageView的userInteractionEnabled默认就是NO,因此UIImageView以及它的子控件默认是不能接收触摸事件的

  • 相关阅读:
    富文本的一般处理方式,document.getElementById('富文本的ID').contentWindow.document.body.innerHTML = '%s'" %(content)
    本地搭建Jenkins
    if __name__ == '__main__'是什么意思?如何理解?看到一个很有用的解答
    关于执行webdriver.Chrome; 报错WebDriverException: Message: unknown error: Element is not clickable at point (1085, 103)
    【转载】学习总结——接口测试基础
    fiddler使用——配置抓取https,出现提示“禁用解密”“单击配置”
    算法(二叉树-矩阵-堆排序)
    算法(递归)---写的很乱
    ES6高级技巧(二)
    ES6高级使用技巧(reduce,filter篇)
  • 原文地址:https://www.cnblogs.com/someonelikeyou/p/5220778.html
Copyright © 2020-2023  润新知