iOS事件攔截及應用

1.概述安全

  咱們知道事件的分發是由Application到Window再到各級View的,因此顯然最安全可靠的攔截地方是Application。這裏攔截事件後若是不手動往下分發,則進入hit-test View過程的機會都沒有。app

  UIApplication和UIWindow都有sendEvent:方法,用來分發Event。咱們能夠繼承類,從新實現sendEvent:方法,這樣就能夠攔截下事件,完成一些特殊的處理,也能夠利用runtime,將sendEvent:方法替換爲咱們本身的方法,添加一些咱們本身的實現,而後再調用原來的消息流程。函數

2.攔截方式post

  1)利用runtimespa

#import "EventHookObject.h"

#import <objc/objc.h>

#import <objc/runtime.h>

@implementation EventHookObject

+ (void)initialize

{

    Method sendEvent = class_getInstanceMethod([UIApplication class], @selector(sendEvent:));

    Method mySendEvent = class_getInstanceMethod([self class], @selector(mySendEvent:));

    IMP sendEventIMP = method_getImplementation(sendEvent);

    class_addMethod([UIApplication class], @selector(sendEventOri:), sendEventIMP, method_getTypeEncoding(sendEvent));

    IMP mySendEventIMP = method_getImplementation(mySendEvent);

    class_replaceMethod([UIApplication class], @selector(sendEvent:), mySendEventIMP, method_getTypeEncoding(sendEvent));

}

 
/*

 * 截獲到UIApplication的sendEvent

 * 咱們能夠先處理完之後,再繼續調用正常處理流程

 */

- (void)mySendEvent:(UIEvent*)event {

    //這裏能夠添加一些你想要的處理

    [self performSelector:@selector(sendEventOri:) withObject:event];

}

 

 而後就是在函數- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions內調用便可code

  2)繼承UIApplication類,實現本身的sendEvent:orm

  應用場景以下,好比應用要求在非某個特定view的區域觸摸時進行一項處理。blog

  咱們固然能夠在其他每個view裏面增長代碼進行判斷,不過這樣比較累,容易漏掉一些地方,比較簡單的解決方案就是在繼承UIApplication類,實現本身的sendEvent:,在這個方法裏面初步過濾一下事件,是觸摸事件就發送Notification,而特定的view會註冊這個Notification,收到後判斷一下是否觸摸到了本身以外的區域。繼承

#import "EventApplication.h"
 
NSString *const NotificationScreenTouch = @"NotificationScreenTouch";
 
@implementation EventApplication
 
- (void)sendEvent:(UIEvent *)event
{
    if (event.type == UIEventTypeTouches) {

        if ([[event.allTouches anyObject] phase] == UITouchPhaseBegan) {

            [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:NotificationScreenTouch object:nil userInfo:[NSDictionary dictionaryWithObject:event forKey:@"value"]]];
        }
    }

    [super sendEvent:event];
}
 
@end

在main.m文件中替換掉UIApplication的調用事件

#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import "EventApplication.h"
 
int main(int argc, char *argv[])
{
    @autoreleasepool {
        //return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
        return UIApplicationMain(argc, argv, NSStringFromClass([EventApplication class]), NSStringFromClass([AppDelegate class]));
    }
}

這樣咱們就實現了事件的預處理,抓住了源頭,想作啥均可以。

相關文章
相關標籤/搜索