iOS事件拦截处理

前面分析了一通iOS事件的分发,主要介绍了事件如何找到处理的view,又是如何按照responder chain逐级传递的。这篇文章主要介绍iOS事件的拦截以及特殊处理。

        我们知道事件的分发是由Application到Window再到各级View的,所以显然最安全可靠的拦截地方是Application。这里拦截事件后如果不手动往下分发,则进入hit-test View过程的机会都没有。

        UIApplication和UIWindow都有sendEvent:方法,用来分发Event。我们可以继承类,重新实现sendEvent:方法,这样就可以拦截下事件,完成一些特殊的处理。

        比如:有一个iPad应用,要求在非某个特定view的区域触摸时进行一项处理。

        我们当然可以在其余每一个view里面增加代码进行判断,不过这样比较累,容易漏掉一些地方;另外当UI需求变更时,维护的GG往往会栽进这个坑,显然这不是一个好方法。

        这里比较简单的解决方案就是在继承UIApplication类,实现自己的sendEvent:,在这个方法里面初步过滤一下事件,是触摸事件就发送Notification,而特定的view会注册这个Notification,收到后判断一下是否触摸到了自己之外的区域。

        恩,还是上代码吧,比较清楚一点:

1. 继承UIApplication的DPApplication类

[objc]  view plain copy
  1. #import <UIKit/UIKit.h>  
  2.   
  3. extern NSString *const notiScreenTouch;  
  4.   
  5. @interface DPApplication : UIApplication  
  6.   
  7. @end  

[objc]  view plain copy
  1. #import "DPApplication.h"  
  2.   
  3. NSString *const notiScreenTouch = @"notiScreenTouch";  
  4.   
  5. @implementation DPApplication  
  6.   
  7. - (void)sendEvent:(UIEvent *)event  
  8. {  
  9.     if (event.type == UIEventTypeTouches) {  
  10.         if ([[event.allTouches anyObject] phase] == UITouchPhaseBegan) {  
  11.             [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:notiScreenTouch object:nil userInfo:[NSDictionary dictionaryWithObject:event forKey:@"data"]]];  
  12.         }  
  13.     }  
  14.     [super sendEvent:event];  
  15. }  
  16.   
  17. @end  
2.要在main.m文件中替换掉UIApplication的调用

[objc]  view plain copy
  1. #import <UIKit/UIKit.h>  
  2.   
  3. #import "AppDelegate.h"  
  4. #import "DPApplication.h"  
  5.   
  6. int main(int argc, charchar *argv[])  
  7. {  
  8.     @autoreleasepool {  
  9.         //return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));  
  10.         return UIApplicationMain(argc, argv, NSStringFromClass([DPApplication class]), NSStringFromClass([AppDelegate class]));  
  11.     }  
  12. }  
3. 这时已经实现了拦截消息,并在touchBegan的时候发送Notification,下面就是在view里面注册这个Notification并处理

[objc]  view plain copy
  1. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onScreenTouch:) name:notiScreenTouch object:nil];  

[objc]  view plain copy
  1. - (void)onScreenTouch:(NSNotification *)notification  
  2. {  
  3.     UIEvent *event=[notification.userInfo objectForKey:@"data"];  
  4.       
  5.     NSLog(@"touch screen!!!!!");  
  6.     CGPoint pt = [[[[event allTouches] allObjects] objectAtIndex:0] locationInView:self.button];  
  7.     NSLog(@"pt.x=%f, pt.y=%f", pt.x, pt.y);  
  8. }  

        这样就实现了事件的预处理,固有的事件处理机制也没有破坏,这个预处理是静悄悄的进行的。当然,如果我需要把某些事件过滤掉,也只需在DPApplication的sendEvent:方法里面抛弃即可。

转载地址:http://blog.csdn.net/sakulafly/article/details/18792631

你可能感兴趣的:(iOS事件拦截处理)