国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > iOS > 正文

淺析iOS之FirstResponder的介紹

2020-02-19 15:52:12
字體:
來源:轉載
供稿:網友

在iOS中,UIEvent類表示當事件發生時系統收集相關的事件信息,當我們創建UIEvent對象后,對事件轉發到應用程序上,下面是武林技術小編淺析iOS之FirstResponder的介紹。

1. UIResonder

對于C#里所有的控件(例如TextBox),都繼承于Control類。而Control類的繼承關系如
下:

復制代碼 代碼如下:

System.Object

?

? System.MarshalByRefObject

??? System.ComponentModel.Component

????? System.Windows.Forms.Control


對于iOS里的UI類,也有類似的繼承關系。

?

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

具體架構可以參見:

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

UIResponder是UIKit框架中的類(Mac OS X Cocoa對應的是AppKit框架)。

?

2. 第一響應對象

在應用的響應對象里,會有一個成為第一響應對象。

第一響應對象和其他響應對象之間有什么區別?對于普通的觸摸事件沒什么區別。就算
我把一個按鈕設置成第一響應對象,當我點擊其他按鈕時,還是會響應其他按鈕,而不
會優先響應第一響應對象。

第一響應對象的區別在于負責處理那些和屏幕位置無關的事件,例如搖動。

蘋果官方文檔的說法是:第一響應對象是窗口中,應用程序認為最適合處理事件的對象

一個班只能有一個班長,應用的響應對象中,只能有一個響應對象成為第一響應對象。

?

3. 成為與取消第一響應對象。

要當第一響應對象,還需要有View來毛遂自薦:

復制代碼 代碼如下:

- (BOOL) canBecomeFirstResponder
{
??? returnYES;
}

?

如果缺少了這段,就算用[view becomeFirstResponder]也不能讓一個view成為第一響應
對象。。。強扭的瓜不甜?好吧不是這個原因。大多數視圖默認只關心與自己有關聯的
事件,并且(幾乎)總是有機會來處理這些事件。以UIButton為例,當用戶單擊某個UIB
utton對象時,無論當前的第一響應對象是哪個視圖,該對象都會收到指定的動作消息。
當上第一響應對象吃力不討好么。。。所以只能由某個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-firs
t-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

?

6.View的FirstResponder的釋放問題
今天遇到一個問題,當我隱藏掉一個正在接受用戶輸入的UITextField的時候,鍵盤并不會消失,而且鍵盤仍然接受用戶輸入,再次顯示該TextField時候發現在隱藏狀態下,所有的輸入仍然傳輸到了該TextField中,于是查下官方資料找到如下解釋:
?
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.???
?
  意思是如果這個View是當前的第一響應者的時候,隱藏該View并不會自動放棄其第一響應者的身份,而且會繼續以第一響應者的身份接受消息。我們可以通過在隱藏View之前,手動調用resignFirstResponder來強制該view放棄第一響應者身份。
?
  下面請看小例子:

復制代碼 代碼如下:

SvTestFirstResponder.h

?

//
//? SvTestFirstResponder.h
//
//? Created by maple on 3/15/12.
//? Copyright (c) 2012 SmileEvday. All rights reserved.
//
//? 當一個view時當前響應者時,調用其hidden方法并不會自動放棄第一響應者身份,所有的消息仍然會發送到這個view
//? 可以通過在hidden前強制放棄第一響應者,恢復正常的消息傳遞
//

#import

?

@interface SvTestFirstResponder : UIView {
??? UITextField *_inputField;
}

@end

?

復制代碼 代碼如下:

?


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

?

這個簡單的例子中,當輸入框進入接受用戶輸入狀態的時候,點擊hide按鈕,鍵盤并不會消失而且會繼續接收用戶輸入并且將用戶輸入傳到TextField中去,后面再點擊Show按鈕的時候你會發現所有在隱藏狀態下輸入的文字都已經成功的被接收。我們可以修改hide方法如下:
?

復制代碼 代碼如下:

- (void)hiddenInputView:(id)sender

?

{

??? if (_inputField.isFirstResponder) {

??????? [_inputField resignFirstResponder];

??? }

??? _inputField.hidden = YES;

}

以上代碼都是武林技術頻道小編和大家分享的淺析iOS之FirstResponder的介紹,希望對大家的學習有一定的幫助!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 石家庄市| 揭阳市| 张家界市| 泉州市| 越西县| 祁阳县| 蒲城县| 壤塘县| 玉田县| 永吉县| 太仆寺旗| 古丈县| 宁阳县| 嵊泗县| 沅江市| 龙江县| 布尔津县| 和平县| 榆树市| 安龙县| 勃利县| 永福县| 探索| 温州市| 资中县| 清徐县| 大宁县| 白河县| 托克逊县| 托里县| 通渭县| 汶上县| 广平县| 红安县| 闵行区| 铜鼓县| 宣威市| 宣威市| 桂阳县| 铜鼓县| 隆化县|