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. 如何配置Java环境变量[转]

    https://jingyan.baidu.com/article/fd8044fa2c22f15031137a2a.html

  2. redis集群密码设置

    1.密码设置(推荐)方式一:修改所有Redis集群中的redis.conf文件加入: masterauth passwd123 requirepass passwd123 说明:这种方式需要重新启动各 ...

  3. 33.MySQL高可用架构

    33.高可用架构33.1 MMM架构MMM(Master-Master replication manager for MySQL)是一套支持双主故障切换和双主日常管理的脚本程序(Perl).主要用来 ...

  4. git 添加分支并与远程连接

    今天由于项目需要,要改版,为了不影响当前网站,所以用分支来管理 首先,在本地添加分支dev git checkout -b dev 提交远程,让同事拉取这个分支,我是直接push了,推到远程. 同事在 ...

  5. 判断是否是json

    转:https://blog.csdn.net/dy_smile/article/details/46739251 function isJson(obj) { var isjson = typeof ...

  6. python 03 字符串详解

    1.制表符 \t str.expandtabs(20) 可相当于表格 2.def   isalpha(self) 判断是否值包含字母(汉字也为真),不包含数字 3.def   isdecimal(se ...

  7. ad_imh

    1. stc15    ad_1.7  9600 1t #include < #include <absacc.h> #include <stdio.h> #includ ...

  8. PowerShell 脚本中调用密文密码

    1. 把密码转变为加密的字符串.使用命令 ConvertFrom-SecureString Read-Host "Enter Password" -AsSecureString | ...

  9. 解决 “access violation at address xxxxxxxxx”错误

    在进行磁盘整理的时候,打开Foxmail的时候出现了“access violation at address32383137”错误 和“access violation at address00000 ...

  10. 阿里巴巴Java开发规约插件安装使用指南

    编码规范插件安装使用指南 阿里技术公众号于今年的2月9日首次公布<阿里巴巴Java开发规约>,瞬间引起全民代码规范的热潮,后又发布了PDF的终极版,大家踊跃留言,期待配套的静态扫描工具开放 ...