iOS在一段时间不活动后执行操作(无用户交互) [英] iOS perform action after period of inactivity (no user interaction)

查看:539
本文介绍了iOS在一段时间不活动后执行操作(无用户交互)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何根据用户交互(或缺少用户交互)向我的iOS应用添加计时器?换句话说,如果2分钟内没有用户交互,我想让应用程序执行某些操作,在这种情况下导航到初始视图控制器。如果在1:55有人触摸屏幕,则计时器将重置。我认为这需要一个全局计时器,所以无论你在哪个视图,缺乏交互启动计时器。虽然,我可以在每个视图上创建一个独特的计时器。有没有人有任何建议,链接或示例代码之前已经完成?

How can I add a timer to my iOS app that is based on user interaction (or lack thereof)? In other words, if there is no user interaction for 2 minutes, I want to have the app do something, in this case navigate to the initial view controller. If at 1:55 someone touches the screen, the timer resets. I would think this would need to be a global timer so no matter which view you are on, the lack of interaction starts the timer. Although, I could create a unique timer on each view. Does anyone have any suggestions, links or sample code where this has been done before?

推荐答案

Anne提供的链接很棒起点,但是,作为我的n00b,很难转化为我现有的项目。我发现一个博客[原始博客不再存在]提供了更好的一步一步,但它不是为XCode 4.2和使用故事板编写的。这里是我如何让不活动计时器适用于我的应用程序:

The link that Anne provided was a great starting point, but, being the n00b that I am, it was difficult to translate into my existing project. I found a blog [original blog no longer exists] that gave a better step-by-step, but it wasn't written for XCode 4.2 and using storyboards. Here is a write up of how I got the inactivity timer to work for my app:


  1. 创建一个新文件 - >目标-C class - >键入一个名称(在我的例子中是TIMERUIApplication)并将子类更改为UIApplication。您可能必须在子类字段中手动键入它。您现在应该拥有相应的.h和.m文件。

  1. Create a new file -> Objective-C class -> type in a name (in my case TIMERUIApplication) and change the subclass to UIApplication. You may have to manually type this in the subclass field. You should now have the appropriate .h and .m files.

将.h文件更改为如下所示:

Change the .h file to read as follows:

#import <Foundation/Foundation.h>

//the length of time before your application "times out". This number actually represents seconds, so we'll have to multiple it by 60 in the .m file
#define kApplicationTimeoutInMinutes 5

//the notification your AppDelegate needs to watch for in order to know that it has indeed "timed out"
#define kApplicationDidTimeoutNotification @"AppTimeOut"

@interface TIMERUIApplication : UIApplication
{
    NSTimer     *myidleTimer;
}

-(void)resetIdleTimer;

@end


  • 将.m文件更改为读取为如下:

  • Change the .m file to read as follows:

    #import "TIMERUIApplication.h"
    
    @implementation TIMERUIApplication
    
    //here we are listening for any touch. If the screen receives touch, the timer is reset
    -(void)sendEvent:(UIEvent *)event
    {
        [super sendEvent:event];
    
        if (!myidleTimer)
        {
            [self resetIdleTimer];
        }
    
        NSSet *allTouches = [event allTouches];
        if ([allTouches count] > 0)
        {
            UITouchPhase phase = ((UITouch *)[allTouches anyObject]).phase;
            if (phase == UITouchPhaseBegan)
            {
                [self resetIdleTimer];
            }
    
        }
    }
    //as labeled...reset the timer
    -(void)resetIdleTimer
    {
        if (myidleTimer)
        {
            [myidleTimer invalidate];
        }
        //convert the wait period into minutes rather than seconds
        int timeout = kApplicationTimeoutInMinutes * 60;
        myidleTimer = [NSTimer scheduledTimerWithTimeInterval:timeout target:self selector:@selector(idleTimerExceeded) userInfo:nil repeats:NO];
    
    }
    //if the timer reaches the limit as defined in kApplicationTimeoutInMinutes, post this notification
    -(void)idleTimerExceeded
    {
        [[NSNotificationCenter defaultCenter] postNotificationName:kApplicationDidTimeoutNotification object:nil];
    }
    
    
    @end
    


  • 进入Supporting Files文件夹并将main.m更改为此(与以前版本的XCode不同):

  • Go into your Supporting Files folder and alter main.m to this (different from prior versions of XCode):

    #import <UIKit/UIKit.h>
    
    #import "AppDelegate.h"
    #import "TIMERUIApplication.h"
    
    int main(int argc, char *argv[])
    {
        @autoreleasepool {
            return UIApplicationMain(argc, argv, NSStringFromClass([TIMERUIApplication class]), NSStringFromClass([AppDelegate class]));
        }
    }
    


  • 在AppDelegate中写下剩余的代码。 m档。我遗漏了与此过程无关的代码。 .h文件中没有更改。

  • Write the remaining code in your AppDelegate.m file. I've left out code not pertaining to this process. There is no change to make in the .h file.

    #import "AppDelegate.h"
    #import "TIMERUIApplication.h"
    
    @implementation AppDelegate
    
    @synthesize window = _window;
    
    -(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
    {      
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidTimeout:) name:kApplicationDidTimeoutNotification object:nil];
    
        return YES;
    }
    
    -(void)applicationDidTimeout:(NSNotification *) notif
    {
        NSLog (@"time exceeded!!");
    
    //This is where storyboarding vs xib files comes in. Whichever view controller you want to revert back to, on your storyboard, make sure it is given the identifier that matches the following code. In my case, "mainView". My storyboard file is called MainStoryboard.storyboard, so make sure your file name matches the storyboardWithName property.
        UIViewController *controller = [[UIStoryboard storyboardWithName:@"MainStoryboard" bundle:NULL] instantiateViewControllerWithIdentifier:@"mainView"];
    
        [(UINavigationController *)self.window.rootViewController pushViewController:controller animated:YES];
    }
    


  • 注意:计时器将在任何时候检测到触摸时启动。这意味着如果用户触摸主屏幕(在我的情况下为mainView),即使没有离开该视图,相同的视图也会在分配的时间后自行移动。对我的应用来说并不是什么大不了的事,但对你的应用来说可能不是。只有在识别到触摸时,计时器才会重置。如果您想在返回到想要的页面时立即重置计时器,请在...之后包含此代码... pushViewController:controller animated:YES];

    Notes: The timer will start anytime a touch is detected. This means that if the user touches the main screen (in my case "mainView") even without navigating away from that view, the same view will push over itself after the allotted time. Not a big deal for my app, but for yours it might be. The timer will only reset once a touch is recognized. If you want to reset the timer as soon as you get back to the page you want to be at, include this code after the ...pushViewController:controller animated:YES];

    [(TIMERUIApplication *)[UIApplication sharedApplication] resetIdleTimer];
    

    如果视图只是坐在那里没有交互,这将导致视图每x分钟推送一次。每次识别触摸时计时器仍然会重置,这样仍可以正常工作。

    This will cause the view to push every x minutes if it's just sitting there with no interaction. The timer will still reset every time it recognizes a touch, so that will still work.

    如果您有建议的改进,请发表评论,特别是如果 mainView目前正在显示。我似乎无法找出我的if语句来让它注册当前视图。但我很满意我所处的位置。下面是我对if语句的初步尝试,以便你可以看到我的目标。

    Please comment if you have suggested improvements, especially someway to disable the timer if the "mainView" is currently being displayed. I can't seem to figure out my if statement to get it to register the current view. But I'm happy with where I'm at. Below is my initial attempt at the if statement so you can see where I was going with it.

    -(void)applicationDidTimeout:(NSNotification *) notif
    {
        NSLog (@"time exceeded!!");
        UIViewController *controller = [[UIStoryboard storyboardWithName:@"MainStoryboard" bundle:NULL] instantiateViewControllerWithIdentifier:@"mainView"];
    
        //I've tried a few varieties of the if statement to no avail. Always goes to else.
        if ([controller isViewLoaded]) {
            NSLog(@"Already there!");
        }
        else {
            NSLog(@"go home");
            [(UINavigationController *)self.window.rootViewController pushViewController:controller animated:YES];
            //[(TIMERUIApplication *)[UIApplication sharedApplication] resetIdleTimer];
        }
    }
    

    我仍然是n00b,可能还没有完成所有事情最好的办法。建议随时欢迎。

    I am still a n00b and may have not done everything the best way. Suggestions are always welcome.

    这篇关于iOS在一段时间不活动后执行操作(无用户交互)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆