第一響應(yīng)者

第一響應(yīng)者 (The First Responder)
  什么是第一響應(yīng)者导披?簡單的講贰您,第一響應(yīng)者是一個UIWindow對象接收到一個事件后刁赖,第一個來響應(yīng)的該事件的對象逛钻。注意:這個第一響應(yīng)者與觸摸檢測到的第一個響應(yīng)的UIView并不是一個概念贬蛙。第一響應(yīng)者一般情況下用于處理非觸摸事件(手機搖晃雨女、耳機線控的遠程空間)或非本窗口的觸摸事件(鍵盤觸摸事件),通俗點講其實就是管別人閑事的響應(yīng)者阳准。在IOS中氛堕,當(dāng)然管閑事并不是所有控件都愿意的,這么說好像并不是很好理解野蝇,或著是站在編程人員的角度來看待這個問題讼稚,程序員負(fù)責(zé)告訴系統(tǒng)哪個對象可以成為第一響應(yīng)者(canBecomeFirstResponder),如果方法canBecomeFirstResponder返回YES绕沈,這個響應(yīng)者對象才有資格稱為第一響應(yīng)者锐想。有資格并不代表一定可以成為第一響應(yīng)者,還要becomeFirstResponder正式成為第一響應(yīng)者乍狐。同時也有對應(yīng)的canResignFirstResponder和resignFirstResponder是否可以解除第一響應(yīng)者赠摇。

值得注意的是,一個UIWindow對象在某一時刻只能有一個響應(yīng)者對象可以成為第一響應(yīng)者澜躺。我們可以通過isFirstResponder來判斷某一個對象是否為第一響應(yīng)者蝉稳。

我們可以用蘋果的私有方法來獲得第一響應(yīng)者

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

下面我們用搖一搖事件來說一說第一響應(yīng)者響應(yīng)事件流程

代碼

在視圖控制器中
- (void)viewDidLoad {
    [super viewDidLoad];
    
    HeaderView *headerView = [[HeaderView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 200)];

    headerView.backgroundColor = [UIColor redColor];
    
    [self.view addSubview:headerView];
    
}

- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event {

    NSLog(@"~~~~~~~~~motionBegan");
    
    
    UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
    UIView *firstResponder = [keyWindow performSelector:@selector(firstResponder)];
    
    
}

在晃動手機后,我們可以看到斷點打印的firstResponder為空掘鄙。

斷點

此時的調(diào)用流程為:

調(diào)用流程

這個時候卻響應(yīng)了搖一搖事件耘戚,為什么呢?系統(tǒng)這個時候會找到當(dāng)前視圖操漠,即self.view收津,如果self.view如果不能響應(yīng),則會依據(jù)響應(yīng)鏈找到能夠響應(yīng)該事件的響應(yīng)者浊伙,在這里self.view.nextResponse就是ViewController撞秋,所以會響應(yīng)這個搖一搖事件。

然后我們在HerderView里面加入一些代碼

@interface HeaderView ()

@end

@implementation HeaderView

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        
//        [self becomeFirstResponder];

    }
    return self;
}

//- (BOOL)canBecomeFirstResponder {
//
//    return YES;
//}

- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event {

    UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
    UIView *firstResponder = [keyWindow performSelector:@selector(firstResponder)];
    
}

然后搖一搖事件嚣鄙,發(fā)現(xiàn)HeaderView并沒有響應(yīng)搖一搖事件吻贿,而是還是由ViewController來響應(yīng)的。

然后我們將注釋的部分打開哑子,注意這里讓HeaderView成為響應(yīng)者舅列,注意一定要寫canBecomeFirstResponder函數(shù)肌割,不然HeaderView就算寫了becomeFirstResponder也不能成為第一響應(yīng)者,然后搖一搖可以看到HeaderView的motionBegan調(diào)用了帐要,HeaderView響應(yīng)了這個事件把敞,同時這個時候的第一響應(yīng)者為HeaderView,函數(shù)調(diào)用流程為:

調(diào)用流程

然后將HeaderView的motionBegan函數(shù)注釋掉,搖一搖,然后發(fā)現(xiàn)ViewController的motionBegan函數(shù)調(diào)用了娱颊,這個時候事件由第一響應(yīng)者HeaderView傳遞給了ViewController,事件的調(diào)用流程:

調(diào)用流程

在這里我們看到調(diào)用流程里有forwardMethodIntld函數(shù)耽装,推測他就是在響應(yīng)鏈中的響應(yīng)者無法響應(yīng)事件時進行轉(zhuǎn)發(fā)到下一個響應(yīng)者的函數(shù),

在這里我們可以分析一下

  1. 在HeaderView沒有成為第一響應(yīng)者简烤,搖一搖的時候有一個forwardMethodIntld函數(shù)剂邮,這個時候由self.view進行開始響應(yīng),但是self.view并不能響應(yīng)該事件横侦,然后向上傳遞給ViewController挥萌,而ViewController能夠響應(yīng)事件,然后事件到這里被處理枉侧,不會繼續(xù)傳遞下去引瀑,所以進行了一次轉(zhuǎn)發(fā)。
  2. 在HeaderView成為第一響應(yīng)者榨馁,然后也有搖一搖事件motionBegan響應(yīng)的時候憨栽,事件直接找到第一響應(yīng)者,發(fā)現(xiàn)第一響應(yīng)者能夠響應(yīng)該事件翼虫,事件到此結(jié)束屑柔,所以這里沒有forwardMethodIntld函數(shù),也就沒有進行事件的轉(zhuǎn)發(fā)珍剑。
  3. 在HeaderView成為第一響應(yīng)者掸宛,然后沒有響應(yīng)搖一搖事件motionBegan的時候,ViewController響應(yīng)了該事件招拙,發(fā)現(xiàn)這里有兩個forwardMethodIntld函數(shù)唧瘾,原因是找到第一響應(yīng)者HeaderView的時候,發(fā)現(xiàn)并不能響應(yīng)該事件别凤,然后由響應(yīng)鏈的上一層self.view響應(yīng)饰序,self.view也不能響應(yīng)該事件,然后找到self.view的上一層规哪,即ViewController求豫,然后響應(yīng)該事件,所以這里進行了兩次事件的轉(zhuǎn)發(fā)。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末注祖,一起剝皮案震驚了整個濱河市猾蒂,隨后出現(xiàn)的幾起案子均唉,更是在濱河造成了極大的恐慌是晨,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件舔箭,死亡現(xiàn)場離奇詭異罩缴,居然都是意外死亡,警方通過查閱死者的電腦和手機层扶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進店門箫章,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人镜会,你說我怎么就攤上這事檬寂。” “怎么了戳表?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵桶至,是天一觀的道長。 經(jīng)常有香客問我匾旭,道長镣屹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任价涝,我火速辦了婚禮女蜈,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘色瘩。我一直安慰自己伪窖,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布居兆。 她就那樣靜靜地躺著覆山,像睡著了一般。 火紅的嫁衣襯著肌膚如雪史辙。 梳的紋絲不亂的頭發(fā)上汹买,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天,我揣著相機與錄音聊倔,去河邊找鬼晦毙。 笑死,一個胖子當(dāng)著我的面吹牛耙蔑,可吹牛的內(nèi)容都是我干的见妒。 我是一名探鬼主播,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼甸陌,長吁一口氣:“原來是場噩夢啊……” “哼须揣!你這毒婦竟也來了盐股?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤耻卡,失蹤者是張志新(化名)和其女友劉穎疯汁,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體卵酪,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡幌蚊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了溃卡。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片溢豆。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖瘸羡,靈堂內(nèi)的尸體忽然破棺而出漩仙,到底是詐尸還是另有隱情,我是刑警寧澤犹赖,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布队他,位于F島的核電站,受9級特大地震影響冷尉,放射性物質(zhì)發(fā)生泄漏漱挎。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一雀哨、第九天 我趴在偏房一處隱蔽的房頂上張望磕谅。 院中可真熱鬧,春花似錦雾棺、人聲如沸膊夹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽放刨。三九已至,卻和暖如春尸饺,著一層夾襖步出監(jiān)牢的瞬間进统,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工浪听, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留螟碎,地道東北人。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓迹栓,卻偏偏與公主長得像掉分,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內(nèi)容