zoukankan      html  css  js  c++  java
  • iOS学习笔记6 第一响应对象初涉(First Responder)

    终于苦等到了iOS项目,把PHP项目移交了。但iOS学习停滞了那么长时间大丈夫?不管了,先恶补两天吧,能看到哪里就是哪里,然后边做边学。

     

    今天学了下前台UI,就来说下响应对象(Responder Object)吧。之所以说初涉,是看到教程后面的章节还会涉及触摸,暂时没学到就不写了。

     

    1. UIResonder

    对于C#里所有的控件(例如TextBox),都继承于Control类。而Control类的继承关系如下:

    System.Object 

      System.MarshalByRefObject

        System.ComponentModel.Component

          System.Windows.Forms.Control

    对于iOS里的UI类,也有类似的继承关系。

    例如对于UITextField,继承于UIControl;UIControl继承于UIView,UIView继承于UIResponder,UIResponder继承于NSObject。

    具体架构可以参见:

    http://developer.apple.com/library/ios/#documentation/general/conceptual/Devpedia-CocoaApp/Responder.html

     

     

    UIResponder是UIKit框架中的类(Mac OS X Cocoa对应的是AppKit框架)。

     

    2. 第一响应对象

    在应用的响应对象里,会有一个成为第一响应对象。

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

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

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

    一个班只能有一个班长,应用的响应对象中,只能有一个响应对象成为第一响应对象。

     

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

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

    - (BOOL) canBecomeFirstResponder
    {
        returnYES;
    }

    如果缺少了这段,就算用[view becomeFirstResponder]也不能让一个view成为第一响应对象。。。强扭的瓜不甜?好吧不是这个原因。大多数视图默认只关心与自己有关联的事件,并且(几乎)总是有机会来处理这些事件。以UIButton为例,当用户单击某个UIButton对象时,无论当前的第一响应对象是哪个视图,该对象都会收到指定的动作消息。当上第一响应对象吃力不讨好么。。。所以只能由某个UIResponder明确表示自己愿意成为第一响应对象才行。(我不知道设计上是基于什么考虑。。。安全?)

     

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

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

     

    4. 第一响应对象的任务

    刚才说了第一响应对象可以处理摇动。就来看个范例吧:

     

    - (void) motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
    {
        if(motion == UIEventSubtypeMotionShake)
        {
            NSLog(@"Device is beginning to shake");
            [selfsetCircleColor:[UIColorredColor]];
            [selfsetNeedsDisplay];
        }
    }

    当摇动开始时触发某些行为。

     

    5. 获取当前第一响应对象

    源自这篇讨论:http://stackoverflow.com/questions/1823317/get-the-current-first-responder-without-using-a-private-api 

    提问的家伙用了如下的方式来获取

    UIView   *firstResponder = [keyWindow performSelector:@selector(firstResponder)];

    结果被苹果打回来,说用了非公开的API。。。

    于是这家伙只好苦逼地用递归了:

    implementationUIView (FindFirstResponder)
    - (UIView *)findFirstResponder
    {
        if (self.isFirstResponder) {        
            return self;     
        }
        for (UIView *subView in self.subviews) {
            UIView *firstResponder = [subView findFirstResponder];
            if (firstResponder != nil) {
                return firstResponder;
            }
        }
        return nil;
    } 
    @end

    恩。。。所以如果有必要的话,要么指定一个固定的第一响应对象,要么弄个全局变量来保存当前第一响应对象?

  • 相关阅读:
    sql server 获取本月的始末时间
    超时时间已到
    sql server定时自动备份
    创建连接服务器
    date制作电子时钟
    C#继承(三)
    C# Split分割
    Dom动态添加属性
    date制作电子时钟(二)
    全局遮罩 shade
  • 原文地址:https://www.cnblogs.com/galaxyyao/p/3102261.html
Copyright © 2011-2022 走看看