原文:http://stackoverflow.com/questions/8085188/ios-perform-action-after-period-of-inactivity-no-user-interaction
1. 建立 Objective-C 類,繼承 UIApplication。
2. 編輯 .h 如下:
#import <Foundation/Foundation.h>
//定義應用程式逾時時間,單位為分鐘,因此我們會在這個數上乘以60,以便折算成秒數。
#define kApplicationTimeoutInMinutes 5
//定義通知名稱,其真實內容是字串 "timed out"
#define kApplicationDidTimeoutNotification
@"AppTimeOut"
@interface TIMERUIApplication : UIApplication {
NSTimer *myidleTimer;
}
-(void)resetIdleTimer;
@end
3. 編輯 .m 如下:
#import "TIMERUIApplication.h"
@implementation TIMERUIApplication
// 監聽所有觸摸,當螢幕被觸摸,時鐘將被重設
-(void)sendEvent:(UIEvent *)event {
[super sendEvent:event];
if (!myidleTimer) {
[selfresetIdleTimer];
}
NSSet *allTouches = [eventallTouches];
if ([allTouches count] > 0) {
UITouchPhase phase= ((UITouch *)
[allTouchesanyObject]).phase;
if (phase ==UITouchPhaseBegan) {
[self resetIdleTimer];
}
}
}
//重設時鐘
-(void)resetIdleTimer {
if (myidleTimer) {
[myidleTimerinvalidate];
}
//將逾時時間由分鐘轉換成秒數
int timeout =
kApplicationTimeoutInMinutes* 60;
myidleTimer = [NSTimer
scheduledTimerWithTimeInterval:timeout
target:self
selector:@selector(idleTimerExceeded)
userInfo:nilrepeats:NO];
}
//當達到逾時時間,張貼 kApplicationTimeoutInMinutes通知
-(void)idleTimerExceeded {
[[NSNotificationCenter defaultCenter]
postNotificationName:
kApplicationDidTimeoutNotification
object:nil];
}
@end
4. 修改 main.m :
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import "TIMERUIApplication.h"
int main(int argc, char *argv[]) {
@autoreleasepool {
returnUIApplicationMain(argc, argv,
NSStringFromClass(
[TIMERUIApplicationclass]),
NSStringFromClass(
[AppDelegate
class]));
}
}
5. 接下來編輯 AppDelegate.mfile,不需要編輯 AppDelegate.h。
#import "AppDelegate.h"
#import "TIMERUIApplication.h"
@implementation AppDelegate
@synthesize window = _window;
-(BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:
@selector(applicationDidTimeout:)
name:
kApplicationDidTimeoutNotification
object:nil];
return YES;
}
-(void)applicationDidTimeout:(NSNotification *)notif {
NSLog (@"time exceeded!!");
//這是故事板和xib檔案不同的地方。對於你想跳轉到的 View Controller,確保下面代碼中的id 和故事板中 View Controller 的 Storyboard Identifier 一致。在本例中,即"mainView"。而我的故事板檔案名稱為MainStoryboard.storyboard, 確保你的檔案名稱和 storyboardWithName 參數保持一致。
UIViewController *controller =
[[UIStoryboard
storyboardWithName:@"MainStoryboard"
bundle:NULL]
instantiateViewControllerWithIdentifier:
@"mainView"];
[(UINavigationController*)
self.window.rootViewController
pushViewController:controller
animated:YES];
}
提示: 一旦偵測到觸摸,定時器會被啟動。也就是說,如果使用者觸摸了主視窗(例如“mainView”),哪怕並沒有從主視窗離開,同一個視圖仍然會在指定時間後 push。這在我的 app 中不是問題,但對於你的 app 則可能是個問題。
這將導致視圖每隔 x 分鐘就push 一次。哪怕偵測到觸摸,時鐘仍然會被重設。
這個問題的一種解決方案是,在app delegate 中聲明一個 Bool 成員 idle,這樣,當你想偵測使用者是否無動作時將其設定為 true,如果僅僅是跳轉到 idle view 則設定為false。然後在 TIMERUIApplication 的 idleTimerExceeded 方法中使用如下的 if 語句。在所有你想偵測使用者是否無動作的視圖中,將app delegate 的 idle 設定為 true。對於不需要偵測使用者是否無動作的視圖,將 idle 設定為 false。
-(void)idleTimerExceeded{
AppDelegate *appdelegate = [[UIApplication
sharedApplication] delegate];
if(appdelegate.idle){
[[NSNotificationCenter defaultCenter]
postNotificationName:
kApplicationDidTimeOutNotification
object:nil];
}
}