iOS事件攔截(實現觸控任意位置隱藏指定view)
最開始的想法是當這個選擇器(selectorView)展開的時候,在當前螢幕上加入一個鋪滿整個螢幕的透明button來攔截所有的觸控事件。
可是這個方案實現起來非常麻煩,也不優雅,而且發現button攔截不到scrollView的滑動事件,所以決定放棄。
後來經過經理提醒,在UIApplication下有一個sendEvent函式,可以從這裡入手。
於是找了一下iOS事件機制的資料,sendEvent函式的介紹如下:
sendEvent:
Dispatches an event to the appropriate responder objects in the application.
- (void)sendEvent:(UIEvent *)eventParameters
- event
A object encapsulating the information about an event, including the touches involved.
Discussion
Subclasses may override this method to intercept incoming events for inspection and special dispatching. iOS calls this method for public events only.
Availability
- Available in iOS 2.0 and later.
在iOS系統中有個很重要的概念:Responder。基本上所有的UI相關的控制元件,view和viewcontroller都是繼承自 UIResponder。事件的分發正是通過由控制元件樹所構成的responder chain(響應鏈)所進行的。一個典型的iOS響應鏈如下:
當用戶發起一個事件,比如觸控式螢幕幕或者晃動裝置,系統產生一個事件,同時投遞給UIApplication,而UIApplication則將這個事件傳 遞給特定的UIWindow進行處理(正常情況都一個程式都只有一個UIWindow),然後由UIWindow將這個事件傳遞給特定的物件(即first responder)
並通過響應鏈進行處理。雖然都是通過響應鏈對事件進行處理,但是觸控事件和運動事件在處理上有著明顯的不同(主要體現在確定哪個物件才是他們的first responder):
看起來很對路,觸控事件發生後,會先經過hitTest確定觸控事件發生在哪個view上,然後該事件會經由sendEvent分發到“合適”的物件進行處理,也就是說sendEvent相當於事件的中轉站,在這裡可以攔截所有的iOS事件。
在iOS系統中,一共有三種形式的事件:觸控事件(Touch Event),運動事件(Motion Event)和遠端控制事件(Remote-control Event)。顧名思義,觸控事件就是當用戶觸控式螢幕幕時發生的事件,而運動事件是使用者移動裝置時發生的事件:加速計,重力感應。遠端控制事件可能比較陌 生:如通過耳機進行控制iOS裝置聲音等都屬於遠端控制事件—-下面不展開說,因為和主題無關,詳細的內容可以參考: 《Remote Control of Multimedia》 。
於是理了一下思路,決定就從它入手。
具體流程是這樣:
1.新建一個自定義的UIApplication(MyApplication),並替換系統預設的UIApplication: