定向事件攔截,UIApplication的實(shí)例方法:
- (BOOL)sendAction:(SEL)action to:(nullable id)target from:(nullable id)sender forEvent:(nullable UIEvent *)event;
iOS中,繼承于UIResponder的類能獲得相應(yīng)事件的能力,這類事件為UIControl Actions,基于Target/Action的方式分發(fā)。
根據(jù)事件傳遞鏈,事件由根節(jié)點(diǎn)UIApplication從Window進(jìn)行向下分發(fā)尋找最合適的對象,根據(jù)響應(yīng)者鏈條,從initial view向上尋找做出響應(yīng)的對象。
繼承于UIResponder且基于Target/Action方式的事件,都可以從上面的那個方法中獲得,可以這么理解,UIApplication管理了這類事件,對這類事件進(jìn)行分發(fā)和調(diào)度。
那么在這個方法中,我們能拿到一個事件所有的信息,能切入處理一些全局業(yè)務(wù)邏輯,例如事件統(tǒng)計(jì),在某個條件下屏蔽某一類的響應(yīng)等等。
像下面這樣,我創(chuàng)建一個UIApplication的分類,重寫此方法屏蔽所有的UIButton及其子類的響應(yīng),同時(shí)不對其它類造成影響:
- (BOOL)sendAction:(SEL)action to:(id)target from:(id)sender forEvent:(UIEvent *)event {
if ([sender isKindOfClass:[UIButton class]]) {
NSLog(@"攔截btn");
return NO;
}
return YES;
}
這個時(shí)候會收到一個編譯警告:Category is implementing a method which will also be implemented by its primary class,告知你不應(yīng)該直接在分類中重寫系統(tǒng)的方法,應(yīng)該用子類去實(shí)現(xiàn)。一般來說我們確實(shí)不應(yīng)該這么做,但這個方法的重寫目前看是安全的,我們可以讓編譯器選擇忽略這個警告:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"