iOS 事件傳遞和事件響應

事件的產生

iOS中事件分爲:觸摸事件(Touch Events)、運動事件(Motion Events)、遠程事件(Remote Events),其中最經常使用的事件應該就是Touch Events了。bash

  • 觸摸事件:點擊、滑動等;
  • 運動事件:重力感應、搖一搖等;
  • 遠程事件:耳機上的按鍵控制手機等;

當咱們點擊屏幕就會產生觸摸事件,而系統會將該事件加入到有Application管理的事件隊列中,使用隊列的形式是由於隊列的特色是FIFO,即先進先出,先產生的事件先處理才符合規則。Application會取出隊列中最前面的事件分發到程序的主窗口。ide

事件傳遞

在Application將事件分發到主窗口後就會向下查找最適合處理該事件的視圖。 Application事件隊列->程序主窗口->向下查找最適合處理事件的View 在查找最合適處理事件的視圖過程當中有兩個很是重要的函數:函數

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;
複製代碼

事件是如何找到最適合處理該事件的方法了?

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;函數是返回能夠響應該事件的視圖,若是返回不爲空則該視圖能夠處理該事件,相反返回空則不能處理該事件spa

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;函數返回產生事件的座標是否在該視圖座標系中。返回YES,表明產生事件的點在該視圖座標系上,說明該視圖能夠處理該事件;返回NO,表明產生事件的點不在該視圖座標系中,說明該視圖不能處理該事件。code

理解了以上兩個函數的做用,咱們就能更好的理解事件傳遞的過程。 事件被分發到程序主窗口也就是UIWindow上後,會調用- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event兩個函數已肯定當前視圖能不能處理該事件。當兩個函數都知足條件(即hitTest函數返回不爲空,pointInside返回YES)時,事件會向子視圖傳遞,直到子視圖沒有符合條件的視圖,就認爲本身是最適合處理該事件的視圖。 視圖不能接受觸摸事件有一下幾種狀況:cdn

  1. 不容許交互,userInteractionEnabled = NO
  2. 設置隱藏,父視圖設置了隱藏,或者當前視圖設置了隱藏 hidden = YES
  3. 透明度爲00 ~ 0.01,當視圖的透明度在00 ~ 0.01之間的時候是不能接收事件。

事件響應

理解事件的響應以前,咱們先要了解一個比較重要的概念——響應者對象(UIResponse)。 在iOS中只有繼承自UIResponse的對象才能接收並處理事件,咱們稱其爲響應者對象。 在找到事件的最佳響應者以後會調用touchesBegantouchesMovedtouchedEnded等方法。touch方法默認會將事件沿着響應鏈向下傳遞(touch方法默認不處理事件,只傳遞事件),事件傳遞給下一個響應者處理。也就是事件會沿着響應者鏈傳遞知道被處理或者傳遞到UIApplication被拋棄掉。對象

咱們知道iOS程序中視圖是先後放置的,即視圖之間是有先後關係的。事件的響應則是沿着視圖先後放置的鏈條關係傳遞。響應者鏈的關係圖能夠參考下圖: blog

從上圖咱們能夠知道當前view是控制器的view時,那麼控制器就是下一個響應者,若是當前view不是控制器的view,那麼它的父視圖就是下一個響應者,事件就會向父視圖傳遞。事件在傳遞過程當中若是都沒有處理,則會傳遞給根視圖 UIWindow。若是 UIWindow不能處理事件則會傳遞個 UIApplication對象。若是 UIApplication不能處理,事件則會被拋棄。

以上是我對事件傳遞和事件響應的簡單理解,若有不對的地方請各位指正。繼承

相關文章
相關標籤/搜索