iOS 响应链

来源:互联网 发布:浙江科澜 知乎 编辑:程序博客网 时间:2024/06/08 01:22

首先要明确的是:在IOS中,有响应者链对事件进行响应,所有的响应类都是UIResponder的子类,响应者链是一个由不同对象组成的层次结构,其中的每个对象将依次获得响应事件消息的机会。

响应链的过程:

当事件发生的时候,响应链首先被发送给第一个响应者(往往是事件发生的视图,也就是用户触摸屏幕的地方)。事件将沿着响应者链一直向下传递,直到被接受并作出处理。一般来说,第一响应者是个视图对象或者其子类,当其被触摸后事件就交由它处理,如果他不处理,事件就会被传递给视图控制器对象UIViewController(如果存在),然后是它的父视图对象(superview),以此类推直到顶层视图。接下来会沿着顶层视图(top view)到窗口(UIwindow 对象) 再到程序的(UIApplication对象),如果整个过程都没有响应这个事件,则该事件被丢弃,一般情况下,在响应链中只要有对象处理事件,事件就会被传递。

典型的响应路线图如:

First  Responser --> The Window -->The Applicationn --> App Delegate

正常的响应者链流程经常被委托打断,一个对象可能将响应工作委托给另一个对象来完成(通常是视图控制器viewcontroller)。


关于响应链的常见问题:

1. 如何调用父类的controller中的方法:

[[self  superview].nextResponder method]; 或者 [[[self  superview]  nextResponder ]  method]; 

这两种方法都可以,但是使用的时候最好是进行判断一下:

id next = [self nextResponder];while(![next isKindOfClass:[ViewController class]])//这里跳不出来。。。有人说这里跳不出来,其实是因为它没有当前这个view放入ViewController中,自然也就跳不出来了,会死循环,使用时需要注意。{next = [next nextResponder];}if ([next isKindOfClass:[ViewController class]]){controller = (ViewController *)next;}

2.当一个子view需要接收点击事件,其父view也需要接收点击事件,该如何处理:

按照正常情况下,子类接收点击事件以后,事件不会主动传递到下一个响应者,因此父类便不再接收点击事件。如果子类不处理点击事件,则事件会一直传递下去,直到UIApplication。

但是我们可以使得子类处理过响应事件后仍将响应这传递到下一个响应者。但是我们编写代码才能办到。

要做的如下:子view的代码如下:- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {// 这里可以做子view自己想做的事,做完后,事件继续上传,就可以让其父类,甚至父viewcontroller获取到这个事件了   [[selfnextResponder]touchesBegan:toucheswithEvent:event];}- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {[[selfnextResponder]touchesEnded:toucheswithEvent:event];}- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {[[selfnextResponder] touchesCancelled:toucheswithEvent:event];}- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {[[selfnextResponder] touchesMoved:toucheswithEvent:event];}

补充一段摘要:

摘取一部分说明:

当用户与iPhone的触摸屏产生互动时,硬件就会探测到物理接触并且通知操作系统。接着操作系统就会创建相应的事件并且将其传递给当前正在运行的应用程序的事件队列。然后这项事件会被事件循环传递给优先响应者物件。优先响应者物件是事件被触发时和用户交互的物件,比如  按钮物件、视图物件。如果我们编写了代码让优先响应者处理这种类型的事件,那么它就会处理这种类型的事件。处理完某项事件后,响应者有两个选项:1、将其丢弃;2、将其传递给响应链条中的下一个响应者。下一个响应者的地址存储在当前响应者物件所包含的变量nextResponder当中。如果优先响应者无法处理这一项事件,那么这项事件就传递给下一个响应者,直到这项事件到达能处理它的响应者或者到达响应链条的末端,也就是UIApplication类型的物件。UIApplication类型的物件收到一项事件后,也是要么处理,要么丢弃。

比如  有一个视图物件,这个视图物件上有一个按钮物件。当用户触摸这个按钮物件时,作为优先响应者,这个按钮物件就会收到一项事件。如果这个按钮物件无法处理这项事件,就会将这项事件传递给视图物件。如果视图物件无法处理这项事件,就会将这项事件传递给视图控制器物件。以此类推。

应该注意的 :是当我们在使用响应链条时,一项事件并不会自动地从一个响应者传递到下一个响应者。如果要将一项事件从一个响应者传递到下一个响应者,我们  必须编写代码才能办到

原创粉丝点击