Ссылка, которую предоставила Энн, была отличной отправной точкой, но, поскольку я n00b, мне было трудно перевести мой существующий проект.Я нашел блог [оригинальный блог больше не существует], который давал пошаговое улучшение, но он не был написан для XCode 4.2 и раскадровок.Вот описание того, как я заставил таймер неактивности работать для моего приложения:
Создать новый файл -> класс Objective-C -> ввести имя (в моем случаеTIMERUIApplication) и измените подкласс на UIApplication.Возможно, вам придется вручную ввести это в поле подкласса.Теперь у вас должны быть соответствующие файлы .h и .m.
Измените файл .h следующим образом:
#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 следующим образом:
#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
Перейдите в папку «Вспомогательные файлы» и измените main.m на эту (в отличие от предыдущих версий 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 нет никаких изменений.
#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];
[(TIMERUIApplication *)[UIApplication sharedApplication] resetIdleTimer];
Это приведет квид нажимать каждые х минут, если он просто сидит без взаимодействия.Таймер будет сбрасываться каждый раз, когда он распознает касание, поэтому он все равно будет работать.
Пожалуйста, прокомментируйте, если вы предложили улучшения, особенно если вы хотите отключить таймер, если в данный момент отображается «mainView».Я не могу понять мое заявление if, чтобы заставить его зарегистрировать текущее представление.Но я доволен тем, где я нахожусь.Ниже приведена моя первоначальная попытка утверждения if, чтобы вы могли видеть, куда я шел с ним.
-(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 и, возможно, не сделал все наилучшим образом.Предложения всегда приветствуются.