UIView的Touch事件

處理事件的方法

  • UIView是UIResponder的子類,可以覆蓋下列4個方法處理不同的觸摸事件
   //一根或者多根手指開始觸摸view
   - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
   //一根或者多根手指在view上移動
   - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
   //一根或者多根手指離開view
   - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
   //觸摸結(jié)束前耙册,某個系統(tǒng)事件(例如電話呼入)會打斷觸摸過程
   - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event

UITouch對象

  • 當(dāng)用戶用一根手指觸摸屏幕時,會創(chuàng)建一個與手指相關(guān)聯(lián)的UITouch對象 一根手指對應(yīng)一個UITouch對象

  • UITouch的作用:

    • 保存著跟手指相關(guān)的信息迅涮,比如觸摸的位置囊颅、時間、階段
    • 當(dāng)手指移動時蚓曼,系統(tǒng)會更新同一個UITouch對象,使之能夠一直保存該手指在的觸摸位置
    • 當(dāng)手指離開屏幕時钦扭,系統(tǒng)會銷毀相應(yīng)的UITouch對象
  • UITouch的常見屬性

    //觸摸產(chǎn)生時所處的窗口
    @property(nonatomic,readonly,retain) UIWindow    *window;
    
    //觸摸產(chǎn)生時所處的視圖
    @property(nonatomic,readonly,retain) UIView      *view;
    
    //短時間內(nèi)點按屏幕的次數(shù)纫版,可以根據(jù)tapCount判斷單擊、雙擊或更多的點擊
    @property(nonatomic,readonly) NSUInteger          tapCount;
    
    //記錄了觸摸事件產(chǎn)生或變化時的時間客情,單位是秒
    @property(nonatomic,readonly) NSTimeInterval      timestamp;
    
    //當(dāng)前觸摸事件所處的狀態(tài)
    @property(nonatomic,readonly) UITouchPhase        phase;
    
  • UITouch的常見方法

   //返回值表示觸摸在view上的位置
   //這里返回的位置是針對view的坐標(biāo)系的(以view的左上角為原點(0, 0))
   //調(diào)用時傳入的view參數(shù)為nil的話其弊,返回的是觸摸點在UIWindow的位置
   - (CGPoint)locationInView:(UIView *)view;
   // 該方法記錄了前一個觸摸點的位置
   - (CGPoint)previousLocationInView:(UIView *)view;

UIEvent對象

每產(chǎn)生一個事件癞己,就會產(chǎn)生一個UIEvent對象

  • UIEvent : 稱為事件對象,記錄事件產(chǎn)生的時刻和類型
  • 常見屬性 :
   //事件類型
   //@property(nonatomic,readonly) UIEventType     type;
   //@property(nonatomic,readonly) UIEventSubtype  subtype;
   //事件產(chǎn)生的時間
   @property(nonatomic,readonly) NSTimeInterval  timestamp;
   UIEvent還提供了相應(yīng)的方法可以獲得在某個view上面的觸摸對象(UITouch)

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

  • 發(fā)生觸摸事件后梭伐,系統(tǒng)會將該事件加入到一個由UIApplication管理的事件隊列中

  • UIApplication會從事件隊列中取出最前面的事件痹雅,并將事件分發(fā)下去以便處理,通常糊识,先發(fā)送事件給應(yīng)用程序的主窗口(keyWindow)

  • 主窗口會在視圖層次結(jié)構(gòu)中找到一個最合適的視圖來處理觸摸事件绩社,這也是整個事件處理過程的第一步

  • 找到合適的視圖控件后,就會調(diào)用視圖控件的touches方法來作具體的事件處理
    touchesBegan…
    touchesMoved…
    touchedEnded…

  • 這些touches方法的默認(rèn)做法是將事件順著響應(yīng)者鏈條向上傳遞(不實現(xiàn)touches方法赂苗,系統(tǒng)會自動向上一個響應(yīng)者傳遞)愉耙,將事件交給上一個響應(yīng)者進(jìn)行處理

  • 如果一個事件既想自己處理也想交給上一個響應(yīng)者處理,那么自己實現(xiàn)touches方法哑梳,并且調(diào)用super的touches方法,[super touches、绘盟、鸠真、];

如何找到最合適的控件來處理事件

  • 自己是否能接收觸摸事件龄毡?
  • 觸摸點是否在自己身上吠卷?
  • 從后往前遍歷子控件,重復(fù)前面的兩個步驟
  • 如果沒有符合條件的子控件沦零,那么就自己最適合處理

注意點

  • 如果父控件不能接收觸摸事件祭隔,那么子控件就不可能接收到觸摸事件(掌握)

  • UIView不接收觸摸事件的三種情況:

  • 不接收用戶交互 : userInteractionEnabled = NO

  • 隱藏 : hidden = YES

  • 透明 : alpha = 0.0 ~ 0.01

  • UIImageView的userInteractionEnabled默認(rèn)就是NO,因此UIImageView以及它的子控件默認(rèn)是不能接收觸摸事件的

響應(yīng)者鏈

  • 響應(yīng)者鏈條:是由多個響應(yīng)者對象連接起來的鏈條
  • 作用:能很清楚的看見每個響應(yīng)者之間的聯(lián)系路操,并且可以讓一個事件多個對象處理疾渴。
  • 響應(yīng)者對象:能處理事件的對象

事件傳遞的完整過程

  • 先將事件對象由上往下傳遞(由父控件傳遞給子控件),找到最合適的控件來處理這個事件屯仗。

  • 調(diào)用最合適控件的touches….方法

  • 如果調(diào)用了[super touches….];就會將事件順著響應(yīng)者鏈條往上傳遞搞坝,傳遞給上一個響應(yīng)者

  • 接著就會調(diào)用上一個響應(yīng)者的touches….方法

  • 如何判斷上一個響應(yīng)者

  • 如果當(dāng)前這個view是控制器的view,那么控制器就是上一個響應(yīng)者

  • 如果當(dāng)前這個view不是控制器的view,那么父控件就是上一個響應(yīng)者

響應(yīng)者鏈的事件傳遞過程

  • 如果view的控制器存在,就傳遞給控制器魁袜;如果控制器不存在桩撮,則將其傳遞給它的父視圖
  • 在視圖層次結(jié)構(gòu)的最頂級視圖,如果也不能處理收到的事件或消息峰弹,則其將事件或消息傳遞給window對象進(jìn)行處理
  • 如果window對象也不處理店量,則其將事件或消息傳遞給UIApplication對象
  • 如果UIApplication也不能處理該事件或消息,則將其丟棄

hitTest方法&pointInside方法

hitTest方法

  • 當(dāng)事件傳遞給控件的時候鞠呈,就會調(diào)用控件的這個方法融师,去尋找最合適的view
  • point:當(dāng)前的觸摸點,point這個點的坐標(biāo)系就是方法調(diào)用者
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;

pointInside方法

  • 作用:判斷當(dāng)前這個點在不在方法調(diào)用者(控件)上
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;

hitTest:withEvent:的實現(xiàn)原理

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{

    // 1.判斷當(dāng)前控件能否接收事件
    if (self.userInteractionEnabled == NO || self.hidden == YES || self.alpha <= 0.01) return nil;

    // 2. 判斷點在不在當(dāng)前控件
    if ([self pointInside:point withEvent:event] == NO) return nil;

    // 3.從后往前遍歷自己的子控件
    NSInteger count = self.subviews.count;

    for (NSInteger i = count - 1; i >= 0; i--) {
        UIView *childView = self.subviews[i];

        // 把當(dāng)前控件上的坐標(biāo)系轉(zhuǎn)換成子控件上的坐標(biāo)系
        CGPoint childP = [self convertPoint:point toView:childView];

        UIView *fitView = [childView hitTest:childP withEvent:event];


        if (fitView) { // 尋找到最合適的view
            return fitView;
        }
    }
    // 循環(huán)結(jié)束,表示沒有比自己更合適的view
    return self;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蚁吝,一起剝皮案震驚了整個濱河市诬滩,隨后出現(xiàn)的幾起案子霹粥,更是在濱河造成了極大的恐慌,老刑警劉巖疼鸟,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件后控,死亡現(xiàn)場離奇詭異,居然都是意外死亡空镜,警方通過查閱死者的電腦和手機(jī)浩淘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吴攒,“玉大人张抄,你說我怎么就攤上這事⊥菡” “怎么了署惯?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長镣隶。 經(jīng)常有香客問我极谊,道長,這世上最難降的妖魔是什么安岂? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任轻猖,我火速辦了婚禮,結(jié)果婚禮上域那,老公的妹妹穿的比我還像新娘咙边。我一直安慰自己,他們只是感情好次员,可當(dāng)我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布败许。 她就那樣靜靜地躺著,像睡著了一般淑蔚。 火紅的嫁衣襯著肌膚如雪檐束。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天束倍,我揣著相機(jī)與錄音被丧,去河邊找鬼。 笑死绪妹,一個胖子當(dāng)著我的面吹牛甥桂,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播邮旷,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼黄选,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起办陷,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤貌夕,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后民镜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體啡专,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年制圈,在試婚紗的時候發(fā)現(xiàn)自己被綠了们童。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡鲸鹦,死狀恐怖慧库,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情馋嗜,我是刑警寧澤齐板,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站葛菇,受9級特大地震影響甘磨,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜熟呛,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一宽档、第九天 我趴在偏房一處隱蔽的房頂上張望尉姨。 院中可真熱鬧庵朝,春花似錦、人聲如沸又厉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽覆致。三九已至侄旬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間煌妈,已是汗流浹背儡羔。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留璧诵,地道東北人汰蜘。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像之宿,于是被迫代替她去往敵國和親族操。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,877評論 2 345

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