是否有可能以某种方式监听并捕获应用程序中发生的所有触摸事件?
我目前正在开发的应用程序将在展厅和信息亭使用,因此我想恢复到应用程序的开始部分,如果没有触摸已收到给定的几分钟。一种屏幕保护功能,如果你愿意的话。我计划通过在后台运行一个计时器来实现这一点,它应该在每次触摸事件发生在应用程序的某个地方时重置和重新启动。但我怎么能听触摸事件?有什么想法或建议吗?
您需要UIApplication
的子类(我们称之为MyApplication
)。
你修改你的main.m
使用它:
return UIApplicationMain(argc, argv, @"MyApplication", @"MyApplicationDelegate");
之前重写方法[MyApplication sendEvent:]
:
- (void)sendEvent:(UIEvent*)event {
//handle the event (you will probably just reset a timer)
[super sendEvent:event];
}
UIWindow
的子类可以通过覆盖hitTest:
来实现这一点。然后在主窗口的XIB中,有一个对象通常简单地称为Window
。单击它,然后在右侧的实用程序窗格中选择标识(Alt-Command-3)。在Class文本域中,输入UIWindow
子类的名称。
MyWindow.h
@interface MyWindow : UIWindow
@end
MyWindow.m
@implementation MyWindow
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
UIView *res;
res = [super hitTest:point withEvent:event];
// Setup/reset your timer or whatever your want to do.
// This method will be called for every touch down,
// but not for subsequent events like swiping/dragging.
// Still, might be good enough if you want to measure
// in minutes.
return res;
}
@end
您可以使用轻拍手势识别器。子类UITapGestureRecognizer
并导入<UIKit/UIGestureRecognizerSubclass.h>
。它定义了touchesBegan:
、touchesMoved:
、touchesEnded:
和touchesCancelled:
。把你的触摸处理代码放到合适的方法中。
实例化application:didFinishLaunchingWithOptions:
中的手势识别器并将其添加到UIWindow
。将cancelsTouchesInView
设置为NO
,它将透明地传递所有触摸。
出处:this post。
创建一个从UIApplication扩展的类"VApplication"并将这些代码粘贴到相应的类
VApplication.h
#import <Foundation/Foundation.h>
// # of minutes before application times out
#define kApplicationTimeoutInMinutes 10
// Notification that gets sent when the timeout occurs
#define kApplicationDidTimeoutNotification @"ApplicationDidTimeout"
/**
* This is a subclass of UIApplication with the sendEvent: method
* overridden in order to catch all touch events.
*/
@interface VApplication : UIApplication
{
NSTimer *_idleTimer;
}
/**
* Resets the idle timer to its initial state. This method gets called
* every time there is a touch on the screen. It should also be called
* when the user correctly enters their pin to access the application.
*/
- (void)resetIdleTimer;
@end
VApplication.m
#import "VApplication.h"
#import "AppDelegate.h"
@implementation VApplication
- (void)sendEvent:(UIEvent *)event
{
[super sendEvent:event];
// Fire up the timer upon first event
if(!_idleTimer) {
[self resetIdleTimer];
}
// Check to see if there was a touch event
NSSet *allTouches = [event allTouches];
if ([allTouches count] > 0)
{
UITouchPhase phase = ((UITouch *)[allTouches anyObject]).phase;
if (phase == UITouchPhaseBegan)
{
[self resetIdleTimer];
}
}
}
- (void)resetIdleTimer
{
if (_idleTimer)
{
[_idleTimer invalidate];
}
// Schedule a timer to fire in kApplicationTimeoutInMinutes * 60
// int timeout = [AppDelegate getInstance].m_iInactivityTime;
int timeout = 3;
_idleTimer = [NSTimer scheduledTimerWithTimeInterval:timeout
target:self
selector:@selector(idleTimerExceeded)
userInfo:nil
repeats:NO];
}
- (void)idleTimerExceeded
{
/* Post a notification so anyone who subscribes to it can be notified when
* the application times out */
[[NSNotificationCenter defaultCenter]
postNotificationName:kApplicationDidTimeoutNotification object:nil];
}
@end
将类名"VApplication"替换为
像这样的Main.m
文件
int main(int argc, char * argv[])
{
@autoreleasepool {
return UIApplicationMain(argc, argv, @"VApplication", NSStringFromClass([AppDelegate class]));
}
}
为你相应的视图控制器注册一个通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidTimeout:) name:kApplicationDidTimeoutNotification object:nil];
一旦超时,通知将触发并像这样处理事件
- (void) applicationDidTimeout:(NSNotification *) notif //inactivity lead to any progress
{
}
你可以把一个透明视图放在视图层次结构的顶部,并在该视图中选择是处理它接收到的触摸事件还是将它们传递给较低的视图
在Swift 4.21. 创建UIApplication对象的子类并打印用户操作:
import UIKit
class ANUIApplication: UIApplication {
override func sendAction(_ action: Selector, to target: Any?, from sender: Any?, for event: UIEvent?) -> Bool {
print("FILE= (NSStringFromSelector(action)) METHOD=(String(describing: target!)) SENDER=(String(describing: sender))")
return super.sendAction(action, to: target, from: sender, for: event)
}
}
- 在AppDelegate.swift文件中,你会发现应用程序入口点@UIApplicationMain注释并添加新的swift文件main.swift并将以下代码添加到main.swift文件 中
进口UIKitANUIApplication是我们添加动作日志的类。AppDelegate是我们编写应用委托方法的默认应用委托。(有助于在大项目中跟踪动作和文件名)UIApplicationMain (命令行。命令行参数个数、CommandLine.unsafeArgvNSStringFromClass (ANUIApplication.self) NSStringFromClass (AppDelegate.self))