是否有可能以某种方式听取并抓住应用中发生的所有触摸事件?
我正在开发的应用程序将用于展示厅和信息亭,因此如果在给定的几分钟内没有收到任何触摸,我想恢复到应用程序的开始部分。一种屏幕保护功能,如果你愿意的话。我打算通过在后台运行一个计时器来实现这一点,每当应用程序中的某个地方发生触摸事件时,应该重置并重新启动计时器。但是我怎么能听听触摸事件呢?有什么想法或建议吗?
答案 0 :(得分:33)
这很容易。
您需要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];
}
答案 1 :(得分:4)
通过覆盖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
答案 2 :(得分:3)
创建一个类&#34; VApplication&#34;从UIApplication扩展而来 并将这些代码粘贴到相应的类
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
更换班级名称&#34; VApplication&#34;到我们的
的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
{
}
答案 3 :(得分:2)
您可以使用点按手势识别器。子类UITapGestureRecognizer
和导入<UIKit/UIGestureRecognizerSubclass.h>
。这定义了touchesBegan:
,touchesMoved:
,touchesEnded:
和touchesCancelled:
。将您的触摸处理代码放在适当的方法中。
在application:didFinishLaunchingWithOptions:
中实例化手势识别器并将其添加到UIWindow
。将cancelsTouchesInView
设置为NO
,它将透明地传递所有触摸。
信用:this post。
答案 4 :(得分:1)
您可以在视图层次结构的顶部放置透明视图,并在该视图中选择是否处理它接收的触摸事件或将它们传递给较低视图。
答案 5 :(得分:0)
在Swift 4.2中 1.创建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)
}
}
导入UIKit
UIApplicationMain( CommandLine.argc,CommandLine.unsafeArgv, NSStringFromClass(ANUIApplication.self),NSStringFromClass(AppDelegate.self))
ANUIApplication是我们添加了操作日志的类。 AppDelegate是我们编写应用程序委托方法的默认应用程序委托。(有助于跟踪大项目中的动作和文件名)