App在闲置一段时间(也即用户无动作)执行指定动作

来源:互联网 发布:液压系统绘图软件 编辑:程序博客网 时间:2024/06/05 09:30

转载:http://blog.csdn.net/kmyhy/article/details/9716333


原文: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];

           }

}


原创粉丝点击