最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

解析iOS開(kāi)發(fā)中的FirstResponder第一響應(yīng)對(duì)象

 更新時(shí)間:2015年10月15日 09:53:44   作者:一片楓葉  
這篇文章主要介紹了解析iOS開(kāi)發(fā)中的FirstResponder第一響應(yīng)對(duì)象,包括View的FirstResponder的釋放問(wèn)題,需要的朋友可以參考下

1. UIResonder

對(duì)于C#里所有的控件(例如TextBox),都繼承于Control類(lèi)。而Control類(lèi)的繼承關(guān)系如
下:

復(fù)制代碼 代碼如下:

System.Object

  System.MarshalByRefObject

    System.ComponentModel.Component

      System.Windows.Forms.Control


對(duì)于iOS里的UI類(lèi),也有類(lèi)似的繼承關(guān)系。

例如對(duì)于UITextField,繼承于UIControl;UIControl繼承于UIView,UIView繼承于UIRe
sponder,UIResponder繼承于NSObject。

具體架構(gòu)可以參見(jiàn):

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

UIResponder是UIKit框架中的類(lèi)(Mac OS X Cocoa對(duì)應(yīng)的是AppKit框架)。

 

2. 第一響應(yīng)對(duì)象

在應(yīng)用的響應(yīng)對(duì)象里,會(huì)有一個(gè)成為第一響應(yīng)對(duì)象。

第一響應(yīng)對(duì)象和其他響應(yīng)對(duì)象之間有什么區(qū)別?對(duì)于普通的觸摸事件沒(méi)什么區(qū)別。就算
我把一個(gè)按鈕設(shè)置成第一響應(yīng)對(duì)象,當(dāng)我點(diǎn)擊其他按鈕時(shí),還是會(huì)響應(yīng)其他按鈕,而不
會(huì)優(yōu)先響應(yīng)第一響應(yīng)對(duì)象。

第一響應(yīng)對(duì)象的區(qū)別在于負(fù)責(zé)處理那些和屏幕位置無(wú)關(guān)的事件,例如搖動(dòng)。

蘋(píng)果官方文檔的說(shuō)法是:第一響應(yīng)對(duì)象是窗口中,應(yīng)用程序認(rèn)為最適合處理事件的對(duì)象

一個(gè)班只能有一個(gè)班長(zhǎng),應(yīng)用的響應(yīng)對(duì)象中,只能有一個(gè)響應(yīng)對(duì)象成為第一響應(yīng)對(duì)象。

 

3. 成為與取消第一響應(yīng)對(duì)象。

要當(dāng)?shù)谝豁憫?yīng)對(duì)象,還需要有View來(lái)毛遂自薦:

復(fù)制代碼 代碼如下:

- (BOOL) canBecomeFirstResponder
{
    returnYES;
}

如果缺少了這段,就算用[view becomeFirstResponder]也不能讓一個(gè)view成為第一響應(yīng)
對(duì)象。。。強(qiáng)扭的瓜不甜?好吧不是這個(gè)原因。大多數(shù)視圖默認(rèn)只關(guān)心與自己有關(guān)聯(lián)的
事件,并且(幾乎)總是有機(jī)會(huì)來(lái)處理這些事件。以UIButton為例,當(dāng)用戶(hù)單擊某個(gè)UIB
utton對(duì)象時(shí),無(wú)論當(dāng)前的第一響應(yīng)對(duì)象是哪個(gè)視圖,該對(duì)象都會(huì)收到指定的動(dòng)作消息。
當(dāng)上第一響應(yīng)對(duì)象吃力不討好么。。。所以只能由某個(gè)UIResponder明確表示自己愿意成
為第一響應(yīng)對(duì)象才行。(我不知道設(shè)計(jì)上是基于什么考慮。。。安全?)

 

在當(dāng)上第一響應(yīng)對(duì)象時(shí),不同對(duì)象可能會(huì)有一些特殊的表現(xiàn)。例如UITextField當(dāng)上的時(shí)
候,就會(huì)調(diào)出一塊小鍵盤(pán)。

第一響應(yīng)對(duì)象也有可能被辭退。發(fā)送一個(gè)resignFirstResponder,就可以勸退。

 

4. 第一響應(yīng)對(duì)象的任務(wù)

剛才說(shuō)了第一響應(yīng)對(duì)象可以處理?yè)u動(dòng)。就來(lái)看個(gè)范例吧:

 

復(fù)制代碼 代碼如下:

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

當(dāng)搖動(dòng)開(kāi)始時(shí)觸發(fā)某些行為。

 

5. 獲取當(dāng)前第一響應(yīng)對(duì)象

源自這篇討論:http://stackoverflow.com/questions/1823317/get-the-current-firs
t-responder-without-using-a-private-api

提問(wèn)的家伙用了如下的方式來(lái)獲取

復(fù)制代碼 代碼如下:

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

結(jié)果被蘋(píng)果打回來(lái),說(shuō)用了非公開(kāi)的API。。。

于是這家伙只好苦逼地用遞歸了:

復(fù)制代碼 代碼如下:

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

6.View的FirstResponder的釋放問(wèn)題
今天遇到一個(gè)問(wèn)題,當(dāng)我隱藏掉一個(gè)正在接受用戶(hù)輸入的UITextField的時(shí)候,鍵盤(pán)并不會(huì)消失,而且鍵盤(pán)仍然接受用戶(hù)輸入,再次顯示該TextField時(shí)候發(fā)現(xiàn)在隱藏狀態(tài)下,所有的輸入仍然傳輸?shù)搅嗽揟extField中,于是查下官方資料找到如下解釋?zhuān)?br />  
Important If you hide a view that is currently the first responder, the view does not automatically resign its first responder status. Events targeted at the first responder are still delivered to the hidden view. To prevent this from happening, you should force your view to resign the first responder status when you hide it.   
 
  意思是如果這個(gè)View是當(dāng)前的第一響應(yīng)者的時(shí)候,隱藏該View并不會(huì)自動(dòng)放棄其第一響應(yīng)者的身份,而且會(huì)繼續(xù)以第一響應(yīng)者的身份接受消息。我們可以通過(guò)在隱藏View之前,手動(dòng)調(diào)用resignFirstResponder來(lái)強(qiáng)制該view放棄第一響應(yīng)者身份。
 
  下面請(qǐng)看小例子:

復(fù)制代碼 代碼如下:

SvTestFirstResponder.h

//
//  SvTestFirstResponder.h
//
//  Created by maple on 3/15/12.
//  Copyright (c) 2012 SmileEvday. All rights reserved.
//
//  當(dāng)一個(gè)view時(shí)當(dāng)前響應(yīng)者時(shí),調(diào)用其hidden方法并不會(huì)自動(dòng)放棄第一響應(yīng)者身份,所有的消息仍然會(huì)發(fā)送到這個(gè)view
//  可以通過(guò)在hidden前強(qiáng)制放棄第一響應(yīng)者,恢復(fù)正常的消息傳遞
//

#import <UIKit/UIKit.h>

@interface SvTestFirstResponder : UIView {
    UITextField *_inputField;
}

@end


復(fù)制代碼 代碼如下:

SvTestFirstResponder.m

//
//  SvTestFirstResponder.m
//
//  Created by maple on 3/15/12.
//  Copyright (c) 2012 SmileEvday. All rights reserved.
//

#import "SvTestFirstResponder.h"

@interface SvTestFirstResponder()

- (void)hiddenInputView:(id)sender;
- (void)showInputView:(id)sender;

@end

@implementation SvTestFirstResponder

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
       
        _inputField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 200, 50)];
        _inputField.center = CGPointMake(160, 50);
        [_inputField setFont:[UIFont systemFontOfSize:24]];
        _inputField.text = @"input you text";
        _inputField.clearsOnBeginEditing = YES;
        _inputField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
        _inputField.borderStyle = UITextBorderStyleRoundedRect;
        [self addSubview:_inputField];
        _inputField.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
       
        UIButton *hiddenBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        hiddenBtn.frame = CGRectMake(0, 0, 115, 40);
        hiddenBtn.center = CGPointMake(80, 110);
        [hiddenBtn setTitle:@"Hide TextField" forState:UIControlStateNormal];
        [hiddenBtn addTarget:self action:@selector(hiddenInputView:) forControlEvents:UIControlEventTouchUpInside];
        [self addSubview:hiddenBtn];
        hiddenBtn.autoresizingMask = UIViewAutoresizingFlexibleRightMargin;
        hiddenBtn.titleLabel.lineBreakMode = UILineBreakModeTailTruncation;
       
        UIButton *showBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        showBtn.frame = CGRectMake(0, 0, 115, 40);
        showBtn.center = CGPointMake(240, 110);
        [showBtn setTitle:@"Show TextField" forState:UIControlStateNormal];
        [showBtn addTarget:self action:@selector(showInputView:) forControlEvents:UIControlEventTouchUpInside];
        [self addSubview:showBtn];
        showBtn.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
        showBtn.titleLabel.lineBreakMode = UILineBreakModeTailTruncation;
    }
    return self;
}

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

- (void)hiddenInputView:(id)sender
{
    _inputField.hidden = YES;
}

- (void)showInputView:(id)sender
{
    _inputField.hidden = NO;
}

@end

這個(gè)簡(jiǎn)單的例子中,當(dāng)輸入框進(jìn)入接受用戶(hù)輸入狀態(tài)的時(shí)候,點(diǎn)擊hide按鈕,鍵盤(pán)并不會(huì)消失而且會(huì)繼續(xù)接收用戶(hù)輸入并且將用戶(hù)輸入傳到TextField中去,后面再點(diǎn)擊Show按鈕的時(shí)候你會(huì)發(fā)現(xiàn)所有在隱藏狀態(tài)下輸入的文字都已經(jīng)成功的被接收。我們可以修改hide方法如下:
 

復(fù)制代碼 代碼如下:

- (void)hiddenInputView:(id)sender

{

    if (_inputField.isFirstResponder) {

        [_inputField resignFirstResponder];

    }

    _inputField.hidden = YES;

}

  這樣就可以在隱藏之前強(qiáng)制釋放第一響應(yīng)者身份,這個(gè)問(wèn)題比較細(xì)節(jié),但有時(shí)候可能就是這種細(xì)節(jié)問(wèn)題導(dǎo)致一些莫名奇妙的問(wèn)題,在隱藏一些可能成為第一響應(yīng)者的view之前添加強(qiáng)制釋放第一響應(yīng)者身份,可能會(huì)幫我們避免一些奇怪的問(wèn)題,而且也幾乎不會(huì)有什么開(kāi)銷(xiāo),何樂(lè)而不為呢。

相關(guān)文章

最新評(píng)論

怀化市| 广河县| 博客| 始兴县| 北京市| 高要市| 金堂县| 大庆市| 琼结县| 高淳县| 罗江县| 皮山县| 西乌珠穆沁旗| 县级市| 顺昌县| 赤水市| 台北县| 松潘县| 镇巴县| 巴塘县| 阳朔县| 西吉县| 瓮安县| 文昌市| 古浪县| 古交市| 黄陵县| 贵南县| 冕宁县| 青州市| 日土县| 将乐县| 察隅县| 莱阳市| 玉树县| 衡南县| 东明县| 湖南省| 嵊泗县| 石阡县| 新竹县|