UIResponder 详解

来源:互联网 发布:网络课程录制 编辑:程序博客网 时间:2024/06/06 00:15

- (UIResponder * )nextResponder

 

调用父viewcontroller里面的方法

[[self superview ].nextResponder method];

[[[self superview ] nextResponder] method];

[self.nextResponder method];

 

if ([[next nextResponder] isKindOfClass:[ViewController class]])需要递归

{

      controller =(ViewController *)next;

}

 

当一个子view需要接收点击事件,而父view也需要接收点击事件

当然,你可能会说直接调用mysubview.superView即可,这样做也确实是可以做到,但有时子view是不一定知道有这个特定的父view的存在的,如动态添加子view

所以这里就可以用到消息响应链拉技术。

下面要做的也就是,让子view接收这些事件后,同时把这些事件继续向上传,会一直传到UIApplication为止。而在传的过程中,如果子view接收了这些事件,那么事件会自然终止,我们现在可以做的是同时让子view接收事件,而且还让事件不终止,并继续向上传。

摘取一部分说明:

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

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

 

- (BOOL)isFirstResponder;

 

在应用的响应对象里,会有一个成为第一响应对象。第一响应对象和其他响应对象之间有什么区别?对于普通的触摸事件没什么区别。就算我把一个按钮设置成第一响应对象,当我点击其他按钮时,还是会响应其他按钮,而不会优先响应第一响应对象。

第一响应对象的区别在于负责处理那些和屏幕位置无关的事件,例如摇动。

苹果官方文档的说法是:第一响应对象是窗口中,应用程序认为最适合处理事件的对象。一个班只能有一个班长,应用的响应对象中,只能有一个响应对象成为第一响应对象。

成为与取消第一响应对象。

要当第一响应对象,还需要有View来毛遂自荐:

 

- (BOOL)becomeFirstResponder;

- (BOOL)canBecomeFirstResponder;   //default is NO

{

       return YES;

}

        如果缺少了这段,就算用[view becomeFirstResponder]也不能让一个view成为第一响应对象。。。强扭的瓜不甜?好吧不是这个原因。大多数视图默认只关心与自己有关联的事件,并且(几乎)总是有机会来处理这些事件。以UIButton为例,当用户单击某个UIButton对象时,无论当前的第一响应对象是哪个视图,该对象都会收到指定的动作消息。

当上第一响应对象吃力不讨好么。。。所以只能由某个UIResponder明确表示自己愿意成为第一响应对象才行。(我不知道设计上是基于什么考虑。。。安全?)

在当上第一响应对象时,不同对象可能会有一些特殊的表现。例如UITextField当上的时候,就会调出一块小键盘。

第一响应对象也有可能被辞退。发送一个resignFirstResponder,就可以劝退。

 

- (BOOL)canResignFirstResponder;   //default is YES

- (BOOL)resignFirstResponder;


//让界面上的所有可能是第一响应者的对象放弃第一响应

-(void)resignAllFirstResponder:(UIView*)supperView

{

    for (UIView *view in supperView.subviews)

    {

        if ([view isKindOfClass:[UITextViewclass]])

        {

            [view resignFirstResponder];

        }

        else

        {

            if ([[view subviews]count]!=0)

            {

                [self  resignAllFirstResponder:view];

            }

        }

    }

}




0 0