方案一:讓你的應用程序委托子類化 UIApplication。在實現部分,覆蓋 sendEvent:方法:
- (void)sendEvent:(UIEvent *)event {
[super sendEvent:event];
// 只在開始或結束觸摸時 reset 閒置時間, 以減少不必須要的時鐘 reset 動作
NSSet *allTouches = [event allTouches];
if ([allTouches count] > 0) {
// allTouchescount 似乎只會是 1, 因此 anyObject 總是可用的
UITouchPhase phase =((UITouch *)[allTouches anyObject]).phase;
if (phase ==UITouchPhaseBegan || phase == UITouchPhaseEnded)
[self resetIdleTimer];
}
}
- (void)resetIdleTimer {
if (idleTimer) {
[idleTimerinvalidate];
[idleTimerrelease];
}
idleTimer = [[NSTimer scheduledTimerWithTimeInterval:maxIdleTimetarget:self selector:@selector(idleTimerExceeded) userInfo:nil repeats:NO]retain];
}
- (void)idleTimerExceeded {
NSLog(@"idle time exceeded");
}
這裡, maxIdleTime 和 idleTimer 都是實例變量.
此外你要修改 main.m,告訴 UIApplicationMain 使用你的 delegate 類(在這個例子裡,即 AppDelegate)作為主類:
int main(int argc, char *argv[])
{
@autoreleasepool{
return UIApplicationMain(argc, argv, NSStringFromClass([AppDelegateclass]), NSStringFromClass([AppDelegate class]));
}
}
方案二:本方案不需要子類化UIApplication。它能在某個 UIViewController 子類上生效,因此對於只有一個 ViewController(比如一個互動式應用或游戲)相當有用,或者只想在一個 View Controller 中處理用戶閒置時間。
它不會在重置時鐘時重建 NSTimer 對象,而僅僅是修改它的觸發時間。
在你的代碼中,你可以調用 resetIdleTimer 去檢測各種事件(比如加速計的急劇改變)。
@interface MainViewController : UIViewController {
NSTimer*idleTimer;
}
@end
#define kMaxIdleTimeSeconds 60.0
@implementation MainViewController
#pragma mark -
#pragma mark Handling idle timeout
- (void)resetIdleTimer {
if(!idleTimer) {
idleTimer =[[NSTimer scheduledTimerWithTimeInterval:kMaxIdleTimeSeconds target:self selector:@selector(idleTimerExceeded) userInfo:nil repeats:NO] retain];
}
else {
if(fabs([idleTimer.fireDate timeIntervalSinceNow]) < kMaxIdleTimeSeconds-1.0){
[idleTimer setFireDate:[NSDate dateWithTimeIntervalSinceNow:kMaxIdleTimeSeconds]];
}
}
}
- (void)idleTimerExceeded {
[idleTimerrelease];
idleTimer = nil;
[selfstartScreenSaverOrSomethingInteresting];
[selfresetIdleTimer];
}
- (UIResponder *)nextResponder {
[selfresetIdleTimer];
return[super nextResponder];
}
- (void)viewDidLoad {
[superviewDidLoad];
[selfresetIdleTimer];
}
@end
為簡便起見,忽略了內存管理代碼。