標籤:接收 -o 完成 cap UI 事件處理 應用程式 處理過程 影響
每一次將代碼打散再串聯就是一次重構。
https://www.jianshu.com/p/2e074db792ba
iOS中的事件的產生和傳遞3.1.事件的產生
- 發生觸摸事件後,系統會將該事件加入到一個由UIApplication管理的事件隊列中,為什麼是隊列而不是棧?因為隊列的特點是FIFO,即先進先出,先產生的事件先處理才符合常理,所以把事件添加到隊列。
- UIApplication會從事件隊列中取出最前面的事件,並將事件分發下去以便處理,通常,先發送事件給應用程式的主視窗(keyWindow)。
- 主視窗會在視圖階層中找到一個最合適的視圖來處理觸摸事件,這也是整個事件處理過程的第一步。
找到合適的視圖控制項後,就會調用視圖控制項的touches方法來作具體的事件處理。
3.2.事件的傳遞
- 觸摸事件的傳遞是從父控制項傳遞到子控制項
- 也就是UIApplication->window->尋找處理事件最合適的view
注 意
: 如果父控制項不能接受觸摸事件,那麼子控制項就不可能接收到觸摸事件
應用如何找到最合適的控制項來處理事件?
- 1.首先判斷主視窗(keyWindow)自己是否能接受觸摸事件
- 2.判斷觸摸點是否在自己身上
- 3.子控制項數組中從後往前遍曆子控制項,重複前面的兩個步驟(所謂從後往前遍曆子控制項,就是首先尋找子控制項數組中最後一個元素,然後執行1、2步驟)
- 4.view,比如叫做fitView,那麼會把這個事件交給這個fitView,再遍曆這個fitView的子控制項,直至沒有更合適的view為止。
- 5.如果沒有合格子控制項,那麼就認為自己最合適處理這個事件,也就是自己是最合適的view。
UIView不能接收觸摸事件的三種情況:
- 不允許互動:userInteractionEnabled = NO
- 隱藏:如果把父控制項隱藏,那麼子控制項也會隱藏,隱藏的控制項不能接受事件
- 透明度:如果設定一個控制項的透明度<0.01,會直接影響子控制項的透明度。alpha:0.0~0.01為透明。
注 意
:預設UIImageView不能接受觸摸事件,因為不允許互動,即userInteractionEnabled = NO。所以如果希望UIImageView可以互動,需要設定UIImageView的userInteractionEnabled = YES。
總結一下
1.點擊一個UIView或產生一個觸摸事件A,這個觸摸事件A會被添加到由UIApplication管理的事件隊列中(即,首先接收到事件的是UIApplication)。
2.UIApplication會從事件對列中取出最前面的事件(此處假設為觸摸事件A),把事件A傳遞給應用程式的主視窗(keyWindow)。
3.視窗會在視圖階層中找到一個最合適的視圖來處理觸摸事件。(至此,第一步已完成)
index.png
如果想讓某個view不能處理事件(或者說,事件傳遞到某個view那裡就斷了),那麼可以通過剛才提到的三種方式。比如,設定其userInteractionEnabled = NO;那麼傳遞下來的事件就會由該view的父控制項處理。
例如,不想讓藍色的view接收事件,那麼可以設定藍色的view的userInteractionEnabled = NO;那麼點擊黃色的view或者藍色的view所產生的事件,最終會由橙色的view處理,橙色的view就會成為最合適的view。
所以,不管視圖能不能處理事件,只要點擊了視圖就都會產生事件,關鍵在於該事件最終是由誰來處理!也就是說,如果藍色視圖不能處理事件,點擊藍色視圖產生的觸摸事件不會由被點擊的視圖(藍色視圖)處理!
注意:如果設定父控制項的透明度或者hidden,會直接影響到子控制項的透明度和hidden。如果父控制項的透明度為0或者hidden = YES,那麼子控制項也是不可見的!
3.3.(重痛點)如何尋找最合適的view
應用如何找到最合適的控制項來處理事件?
1.首先判斷主視窗(keyWindow)自己是否能接受觸摸事件
2.觸摸點是否在自己身上
3.從後往前遍曆子控制項,重複前面的兩個步驟(首先尋找數組中最後一個元素)
4.如果沒有合格子控制項,那麼就認為自己最合適處理
詳述:1.主視窗接收到應用程式傳遞過來的事件後,首先判斷自己能否接手觸摸事件。如果能,那麼在判斷觸摸點在不在視窗自己身上
2.如果觸摸點也在視窗身上,那麼視窗會從後往前遍曆自己的子控制項(遍曆自己的子控制項只是為了尋找出來最合適的view)
3.遍曆到每一個子控制項後,又會重複上面的兩個步驟(傳遞事件給子控制項,1.判斷子控制項能否接受事件,2.點在不在子控制項上)
4.如此迴圈遍曆子控制項,直到找到最合適的view,如果沒有更合適的子控制項,那麼自己就成為最合適的view。
找到最合適的view後,就會調用該view的touches方法處理具體的事件。所以,只有找到最合適的view,把事件傳遞給最合適的view後,才會調用touches方法進行接下來的事件處理。找不到最合適的view,就不會調用touches方法進行事件處理。
注意:之所以會採取從後往前遍曆子控制項的方式尋找最合適的view只是為了做一些迴圈最佳化。因為相比較之下,後添加的view在上面,降低迴圈次數。
VV木公子
連結:https://www.jianshu.com/p/2e074db792ba
來源:簡書
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。
iOS中的事件的產生和傳遞