iOS在非活动期后执行操作(无用户交互)

如何在iOS应用程序中添加基于用户交互(或缺少交互)的计时器?换句话说,如果2分钟内没有用户交互,我想让应用程序做点什么,在本例中导航到初始视图控制器。如果在1:55有人触摸屏幕,计时器将重置。我认为这需要一个全局计时器,所以无论你在哪个视图上,缺少交互都会启动计时器。不过,我可以在每个视图上创建一个唯一的计时器。是否有人有任何建议、链接或示例代码,这些都是以前做过的

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

  1. 创建一个新文件->Objective-C类->键入一个名称(在我的例子中是TIMERUIApplication),并将子类更改为UIApplication。您可能需要在subclass字段中手动键入此项。您现在应该拥有相应的.h和.m文件

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

    #导入<基础/基础h>
    //应用程序“超时”之前的时间长度。这个数字实际上代表秒,所以我们必须在.m文件中将它乘以60
    #定义KapplicationTimeOutingMinutes 5
    //AppDelegate需要注意的通知,以便知道它确实已“超时”
    #定义[email protected]“AppTimeOut”
    @接口应用程序:UIApplication
    {
    NSTimer*myidleTimer;
    }
    -(无效)重置IDletimer;
    @结束
    
  3. 将.m文件更改为如下所示:

    导入“TIMERUIApplication.h”
    @应用程序的实现时间
    //在这里,我们正在聆听任何触摸。如果屏幕接收到触摸,则定时器复位
    -(void)sendEvent:(UIEvent*)事件
    {
    [超级发送事件:事件];
    如果(!myidleTimer)
    {
    [自复位IDletimer];
    }
    NSSet*AllTouchs=[event AllTouchs];
    如果([AllTouchs计数]>0)
    {
    UITouchPhase=((UITouch*)[AllTouchAnyObject])阶段;
    如果(相位==UITouchPhaseBegan | |相位==UITouchPhaseMoved)
    {
    [自复位IDletimer];
    }
    }
    }
    //如标签所示…重置计时器
    -(无效)重置IDletimer
    {
    if(myidleTimer)
    {
    [myidleTimer失效];
    }
    //将等待时间转换为分钟而不是秒
    int timeout=kApplicationTimeoutInMinutes*60;
    myidleTimer=[NSTimer scheduledTimerWithTimeInterval:超时目标:自选择器:@selector(IdleTimerExcepended)userInfo:nil repeats:NO];
    }
    //如果计时器达到KapplicationTimeOutingMinutes中定义的限制,则发布此通知
    -(无效)空闲时间
    {
    [[NSNotificationCenter defaultCenter]postNotificationName:kApplicationDidTimeoutNotification对象:nil];
    }
    @结束

  4. 进入您的Supporting Files文件夹并将main.m改为(不同于以前版本的XCode):

    #导入<UIKit/UIKit.h>
    #导入“AppDelegate.h”
    #导入“TIMERUIApplication.h”
    int main(int argc,char*argv[])
    {
    @自动释放池{
    返回UIApplicationMain(argc、argv、NSStringFromClass([TIMERUIApplication class])、NSStringFromClass([AppDelegate class]);
    }
    }
    
  5. 在AppDelegate.m文件中编写剩余的代码。我遗漏了与此过程无关的代码。在.h文件中没有要进行的更改

    导入“AppDelegate.h”
    #导入“TIMERUIApplication.h”
    @实现AppDelegate
    @合成窗口=_窗口;
    -(BOOL)应用程序:(UIApplication*)应用程序使用选项完成启动:(NSDictionary*)启动选项
    {
    [[NSNotificationCenter defaultCenter]addObserver:自选择器:@selector(ApplicationIDTimeout:)名称:kApplicationDidTimeoutNotification对象:nil];
    返回YES;
    }
    -(无效)ApplicationIDTimeout:(NSNotification*)notif
    {
    NSLog(@“超过时间!!”);
    //这就是storyboard vs xib文件的作用。在storyboard上,无论您要恢复到哪个视图控制器,请确保为其提供了与以下代码匹配的标识符。在我的示例中为“mainView”。我的storyboard文件名为MainStoryboard.storyboard,因此请确保您的文件名与storyboard WithName属性匹配。
    UIViewController*控制器=[[UIStoryboard Storyboard with name:@“MainStoryboard”bundle:NULL]实例化视图控制器WithiIdentifier:@“mainView”];
    [(UINavigationController*)self.window.rootViewController pushViewController:controller-animated:YES];
    }

注意:只要检测到触摸,计时器就会启动。这意味着,如果用户触摸主屏幕(在我的例子中是“mainView”),即使没有离开该视图,相同的视图也会在分配的时间后自动覆盖。对我的应用程序来说没什么大不了的,但对你的应用程序来说可能是。只有在识别到触摸后,计时器才会重置。如果您想在回到您想要的页面后立即重置计时器,请在…pushViewController:controller animated:YES]之后包含此代码

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

这将导致视图每x分钟推一次,如果它只是坐在那里,没有交互。计时器仍将在每次识别触摸时重置,因此仍将工作

如果您有改进建议,请发表意见,特别是在当前显示“mainView”时禁用计时器的方法。我似乎无法找出if语句来让它注册当前视图。但我对我现在的处境很满意。下面是我对if语句的初步尝试,以便您可以看到我使用它的目的

-(void)applicationIDTimeout:(NSNotification*)notif
{
NSLog(@“超过时间!!”);
UIViewController*控制器=[[UIStoryboard Storyboard with name:@“MainStoryboard”bundle:NULL]实例化视图控制器WithiIdentifier:@“mainView”];
//我尝试了几种if语句,但都没用。总是转到else。
如果([controller isViewLoaded]){
NSLog(@“已经存在!”);
}
否则{
NSLog(@“回家”);
[(UINavigationController*)self.window.rootViewController pushViewController:controller-animated:YES];
//[(TIMERUIApplication*)[UIApplication sharedApplication]resetIdleTimer];
}
}

我仍然是一个n00b,可能并没有以最好的方式做每件事。欢迎提出建议

发表评论