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. Redhat学习(此为草稿,正式笔记之后存放)

    系统组成 版本XX.XX.XX XX主版本,XX副版本(奇数为测试版,偶数为稳定版),修订版本号 , 表示修改的次数(debug) linux主流分支 硬盘分区 /dev/ 硬件设备所在分区 hd 表 ...

  2. jdbcTemplate的简单介绍

    Spring JDBC抽象框架core包提供了JDBC模板类,其中JdbcTemplate是core包的核心类,所以其他模板类都是基于它封装完成的,JDBC模板类是第一种工作模式. JdbcTempl ...

  3. 代码之髓读后感——类&继承

    面向对象 语言中的用语并不是共通的,在不同语言中,同一个用语的含义可能会有很大差别. C++的设计者本贾尼·斯特劳斯特卢普对类和继承给予了正面肯定,然而,"面向对象"这个词的发明者 ...

  4. mysql sql_mode=only_full_group_by错误解析

    实测,解决问题; 1.错误提示: 2.检查参数设置: 3.mysql的配置文件my.cnf里面可以修改, 但是,改完以后,你检查所有的参数设置都是对的,就是运行不了.怎么办?怎么办? 4.如果还是不行 ...

  5. TCP编程

    Socket是网络编程的一个抽象概念,通常我们用一个Socket表示“打开了一个网络连接”,而打开一个Socket需要知道目标计算机的IP地址和端口号,在指定协议类型即可. 客户端 大多数连接就是考的 ...

  6. 一个价格,两份大礼!Mockplus X MindManager限时联合大促

    3月暖春,阳光明媚了,工作量也伴随气温回升了,面对那么多的tasks,效率提升已经迫在眉睫.为了更好的服务产品设计,为各位产品经理.UI设计师.UX设计师等带来更快更简单的设计解决方案,Mockplu ...

  7. Spring Boot学习笔记:整合H2数据库

    H2数据库:java语言编写的嵌入式sql数据库.可以和应用一起打包发布. H2有三种连接模式(Connection Modes): Embedded mode (local connections ...

  8. 微信浏览器Ajax请求返回值走error

    微信浏览器Ajax post请求是返回值走的error $.ajax({ type: "POST", url: "https://XXXX", cache: f ...

  9. 项目部署到服务器上之后request.getRemoteAddr()为什么获取的都是本地地址

    获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的.但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了.如 ...

  10. 服务器安装ubuntu 14.04 server,开机启动屏幕不停滚动错误WRITE SAME failed. Manually zeroing

    昨天给服务器上安装了一个Ubuntu-14.04-server系统,安装完成后系统可以正常启动,但屏幕上一直滚动着一个错误,sda1:WRITE SAME failed. Manually zeroi ...