1.概述

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

  UIApplication和UIWindow都有sendEvent:方法,用来分发Event。我们可以继承类,重新实现sendEvent:方法,这样就可以拦截下事件,完成一些特殊的处理,也可以利用runtime,将sendEvent:方法替换为我们自己的方法,添加一些我们自己的实现,然后再调用原来的消息流程。

2.拦截方式

  1)利用runtime

#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内调用即可

  2)继承UIApplication类,实现自己的sendEvent:

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

  我们当然可以在其余每一个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]));
}
}

这样我们就实现了事件的预处理,抓住了源头,想做啥都可以。

iOS事件拦截及应用的更多相关文章

  1. iOS事件拦截(实现触摸任意位置隐藏指定view)

    项目里有一个需求,类似新浪或者腾讯微博的顶部title栏的类别选择器的消失(在选择器展开的时候,触摸屏幕任何地方使其消失). 最开始的想法是当这个选择器(selectorView)展开的时候,在当前屏 ...

  2. iOS事件机制(一)

    运用的前提是掌握 掌握的本质是理解 本篇内容将围绕iOS中事件及其传递机制进行学习和分析.在iOS中,事件分为三类: 触控事件(单点.多点触控以及各种手势操作) 传感器事件(重力.加速度传感器等) 远 ...

  3. 谈一谈iOS事件的产生和传递

    谈一谈iOS事件的产生和传递 1.事件的产生 发生触摸事件后,系统会将该事件加入到一个由UIApplication管理的事件队列中. UIApplication会从事件队列中取出最前面的事件,并将事件 ...

  4. 讲讲Android事件拦截机制

    简介 什么是触摸事件?顾名思义,触摸事件就是捕获触摸屏幕后产生的事件.当点击一个按钮时,通常会产生两个或者三个事件--按钮按下,这是事件一,如果滑动几下,这是事件二,当手抬起,这是事件三.所以在And ...

  5. 深入浅出iOS事件机制

    原文地址: http://zhoon.github.io/ios/2015/04/12/ios-event.html 本文章将讲解有关iOS事件的传递机制,如有错误或者不同的见解,欢迎留言指出. iO ...

  6. android事件拦截处理机制详解

    前段时间刚接触过Android手机开发,对它的事件传播机制不是很了解,虽然网上也查了相关的资料,但是总觉得理解模模糊糊,似是而非,于是自己就写个小demo测试了一下.总算搞明白了它的具体机制.写下自己 ...

  7. Android 事件拦截机制一种粗鄙的解释

    对于Android事件拦截机制,相信对于大多数Android初学者是一个抓耳挠腮难于理解的问题.其实理解这个问题并不困难. 首先,你的明白事件拦截机制到底是怎么一回事?这里说的事件拦截机制,指的是对触 ...

  8. iOS事件:触摸事件.运动事件.远程控制事件

    iOS中,提供了事件处理:触摸事件,运动事件,远程控制事件.这很大得方便程序猿的工作. 这里先简单做个介绍: // // ViewController.m // demo // // Created ...

  9. Unity3D研究院编辑器之Editor的GUI的事件拦截

    OnGUI是Unity上一个时代的UI系统,而现在运行时的UI系统已经被UGUI取代,但是Editor的UI还是在用老的这一套GUI系统.比如unity编辑器里的所有窗口,布局,按钮,拖动条.滚动等等 ...

随机推荐

  1. [leetcode]24. Swap Nodes in Pairs交换节点对

    Given a linked list, swap every two adjacent nodes and return its head. You may not modify the value ...

  2. (sealed)密封类及密封方法优缺点

    1. 密封类防止被继承 (有利于代码优化, 由于密封类的不被继承性, 代码在搜索此方法时可以直接定位, 不需要一层层的找继承关系) 只有本程序集可以使用 2. 密封类中不需要再写密封方法(一般密封方法 ...

  3. js、jquery、jsp的区别

    1.JSP全称是java server page    JS全称是javaScript 2.最主要的区别是运行位置不同. JSP运行在后台服务器上,混合在HTML中的java程序段用于控制HTML的动 ...

  4. centos平台基于snort、barnyard2以及base的IDS(入侵检测系统)的搭建与测试及所遇问题汇总

    centos平台基于snort.barnyard2以及base的IDS(入侵检测系统)的搭建与测试及所遇问题汇总 原创 2016年12月19日 01:20:03 标签: centos / snort  ...

  5. JavaScript 高阶函数

    高阶函数的英文叫Higher-order function ,什么是高阶函数呢>? JavaScript的函数其实都指向某个变量.既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接 ...

  6. Mingw下载

    http://ismdeep.oss-cn-shenzhen.aliyuncs.com/x86_64-5.3.0-release-posix-seh-rt_v4-rev0.7z

  7. 团队作业第五周(HCL盐酸队)

    一.Alpha版本测试报告 1.测试计划 测试项目 上下移动   左右移动   发射子弹   与敌方坦克进行攻击 2.测试过程 测试截图 错误记录(提交issues到码云团队项目) 3.测试找出的bu ...

  8. 9.3 翻译系列:数据注解特性之Key【EF 6 Code-First 系列】

    原文链接:http://www.entityframeworktutorial.net/code-first/key-dataannotations-attribute-in-code-first.a ...

  9. 背水一战 Windows 10 (75) - 控件(控件基类): FrameworkElement - 基础知识, 相关事件, HorizontalAlignment, VerticalAlignment

    [源码下载] 背水一战 Windows 10 (75) - 控件(控件基类): FrameworkElement - 基础知识, 相关事件, HorizontalAlignment, Vertical ...

  10. 下载 rpm 源码包并重新编译

    $ yumdownloader --source gdb $ rpmbuild --rebuild gdb-7.8.1-30.fc21.src.rpm $ cd ~/rpmbuild/SPECS/ $ ...