iOS-事件處理與如何獲得最佳點(diǎn)擊的View

事件的產(chǎn)生與傳遞

  • 事件是如何產(chǎn)生與傳遞的?

    • 當(dāng)發(fā)生觸摸事件的后,系統(tǒng)會將該事件加入到一個由UIApplication管理的時間隊(duì)列
      中,UIApplication會從事件隊(duì)列中取出最前面的事件,并將這個事件分發(fā)下去,以便處理,主
      窗口即Window 會在視圖層次中找到一個合適的視圖來處理觸摸事件
    • 觸摸事件的傳遞是從父控件傳遞給子控件的,如果父控件不能接受事件,則里面的所有子控件也不能接收事件
  • 當(dāng)一個控件不能接受事件時,一般有幾種情況

    • 不接收用戶交互 userInteractionEnabled = NO
    • 當(dāng)一個控件隱藏時 Hidden = YES
    • 當(dāng)一個控件為透明時

事件的響應(yīng)

用戶點(diǎn)擊屏幕產(chǎn)生的一個觸摸事件,經(jīng)過一系列的傳遞過程后,會找到一個最適合的視圖來處理事件.找到最合適的視圖控件后,就會調(diào)用控件的touches方法來作具體的事件處理.touches的默認(rèn)做法是將事件順著響應(yīng)者鏈條向上傳遞,將事件交給上一個響應(yīng)者處理

  • 什么是響應(yīng)者鏈條?

    • 由多個響應(yīng)者對象連接起來的鏈條
  • 什么是響應(yīng)者對象?

    • 繼承了UIResponder的對象
  • 如何去尋找上一個響應(yīng)者

    • 1.如果當(dāng)前的View是控制器的View,那么控制器就是上一個響應(yīng)者
    • 2.如果當(dāng)前的View不是控制器的View,那么他的父控件就是上一個響應(yīng)者
    • 3.在視圖層次結(jié)構(gòu)的最頂級視圖,如果也不能處理收到的事件或消息,則其將事件或消息傳
      遞給window對象進(jìn)行處理
    • 4.如果window對象也不處理哆档,則其將事件或消息傳遞給UIApplication對象
    • 5.如果UIApplication也不能處理該事件或消息丐谋,則將其丟棄
  • 系統(tǒng)是如何尋找最合適的View*

    • 1.先判斷自己是否能接收觸摸事件
    • 2.再判斷觸摸的當(dāng)前點(diǎn)在不在自己身上
    • 3.如果在自己身上,它會從后往前遍歷子控件,遍歷出每一個控件后,重啟前兩步
    • 4.如果沒有符合條件的子控件,那么自身就是最合適的View

在尋找最合適View的過程中,系統(tǒng)會調(diào)用2個方法

//作用:尋找最適合的View
//什么時候調(diào)用:當(dāng)事件傳遞給當(dāng)前View時就會調(diào)用這個方法
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
    UIView *fitView = [super hitTest:point withEvent:event];
    NSLog(@"%@",fitView);
    return fitView;
}
//作用:判斷觸摸點(diǎn)在不在當(dāng)前的View上.
//什么時候調(diào)用:在hitTest方法當(dāng)中會自動調(diào)用這個方法.
//注意:point必須得要跟當(dāng)前View同一個坐標(biāo)系.
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{
    return YES;
}

那么hitTest: withEvent:方法底層是如何實(shí)現(xiàn)的呢?

// 判斷自己能否接收事件
if(self.userInteractionEnabled == NO || self.hidden == YES || self.alpha <= 0.01){
    return nil;
}
// 觸摸點(diǎn)在不在自己身上
if ([self pointInside:point withEvent:event] == NO) {
    return nil;
}
// 從后往前遍歷自己的子控件(重復(fù)前面的兩個步驟)
int count = (int)self.subviews.count;
for (int i = count -1; i >= 0; i--) {
    UIView *childV = self.subviews[i];
    // point必須得要跟childV相同的坐標(biāo)系.
    // 把point轉(zhuǎn)換childV坐標(biāo)系上面的點(diǎn)
    CGPoint childP = [self convertPoint:point toView:childV];
    UIView *fitView = [childV hitTest:childP withEvent:event];
    if (fitView) {
        return fitView;
    } 
}
// 如果沒有符合條件的子控件,那么就自己最適合處理
return self;

在開發(fā)中或多或少會需要一些特殊的點(diǎn)擊,這里有2個小例子供大家參考

  • 一個按鈕被一個半透明的View部分遮擋,需要點(diǎn)擊到按鈕的時候,按鈕始終響應(yīng)
  • 一個View超出了父視圖的范圍,需要點(diǎn)擊超出范圍的View也有響應(yīng)
    - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
    
        //當(dāng)觸摸點(diǎn)在按鈕上的時候,才讓按鈕去響應(yīng)事件.
        //把當(dāng)前點(diǎn)轉(zhuǎn)換成按鈕坐標(biāo)系上的點(diǎn).
        CGPoint btnP =  [self convertPoint:point toView:self.btn];
        if ( [self.btn pointInside:btnP withEvent:event]) {
            return self.btn;
        }else{
            return [super hitTest:point withEvent:event];
        }
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末奈懒,一起剝皮案震驚了整個濱河市芍躏,隨后出現(xiàn)的幾起案子邪乍,更是在濱河造成了極大的恐慌,老刑警劉巖对竣,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件庇楞,死亡現(xiàn)場離奇詭異,居然都是意外死亡否纬,警方通過查閱死者的電腦和手機(jī)吕晌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來临燃,“玉大人睛驳,你說我怎么就攤上這事烙心。” “怎么了乏沸?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵淫茵,是天一觀的道長。 經(jīng)常有香客問我屎蜓,道長痘昌,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任炬转,我火速辦了婚禮,結(jié)果婚禮上算灸,老公的妹妹穿的比我還像新娘扼劈。我一直安慰自己,他們只是感情好菲驴,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布荐吵。 她就那樣靜靜地躺著,像睡著了一般赊瞬。 火紅的嫁衣襯著肌膚如雪先煎。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天巧涧,我揣著相機(jī)與錄音薯蝎,去河邊找鬼。 笑死谤绳,一個胖子當(dāng)著我的面吹牛占锯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播缩筛,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼消略,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了瞎抛?” 一聲冷哼從身側(cè)響起艺演,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎桐臊,沒想到半個月后胎撤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡豪硅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年哩照,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片懒浮。...
    茶點(diǎn)故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡飘弧,死狀恐怖识藤,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情次伶,我是刑警寧澤痴昧,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站冠王,受9級特大地震影響赶撰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜柱彻,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一豪娜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧哟楷,春花似錦瘤载、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至惩阶,卻和暖如春挎狸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背断楷。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工锨匆, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人脐嫂。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓统刮,卻偏偏與公主長得像,于是被迫代替她去往敵國和親账千。 傳聞我的和親對象是個殘疾皇子侥蒙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評論 2 345

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