iPhone: Обнаружение пользовательской неактивности/времени простоя начиная с последнего экранного касания

152
задан TheNeil 16 May 2019 в 00:21
поделиться

4 ответа

Вот ответ, который я искал:

Имеют Ваш UIApplication подкласса делегата приложения. В файле реализации переопределите sendEvent: метод как так:

- (void)sendEvent:(UIEvent *)event {
    [super sendEvent:event];

    // Only want to reset the timer on a Began touch or an Ended touch, to reduce the number of timer resets.
    NSSet *allTouches = [event allTouches];
    if ([allTouches count] > 0) {
        // allTouches count only ever seems to be 1, so anyObject works here.
        UITouchPhase phase = ((UITouch *)[allTouches anyObject]).phase;
        if (phase == UITouchPhaseBegan || phase == UITouchPhaseEnded)
            [self resetIdleTimer];
    }
}

- (void)resetIdleTimer {
    if (idleTimer) {
        [idleTimer invalidate];
        [idleTimer release];
    }

    idleTimer = [[NSTimer scheduledTimerWithTimeInterval:maxIdleTime target:self selector:@selector(idleTimerExceeded) userInfo:nil repeats:NO] retain];
}

- (void)idleTimerExceeded {
    NSLog(@"idle time exceeded");
}

, где maxIdleTime и idleTimer являются переменными экземпляра.

Для этого для работы также необходимо изменить main.m, чтобы сказать UIApplicationMain использовать класс делегата (в этом примере, AppDelegate) как основной класс:

int retVal = UIApplicationMain(argc, argv, @"AppDelegate", @"AppDelegate");
152
ответ дан Mike McMaster 23 November 2019 в 22:10
поделиться

В конечном счете необходимо ли определить то, что Вы считаете неактивными - неактивно результат пользователя, не касающегося экрана, или действительно ли это - состояние системы, если никакие вычислительные ресурсы не используются? Возможно, во многих приложениях, для пользователя сделать что-то даже если, не активно взаимодействуя с устройством через сенсорный экран. В то время как пользователь, вероятно, знаком с понятием засыпания устройства и уведомления, что это произойдет через экранное потускнение, не обязательно имеет место, что они будут ожидать, что что-то произойдет, если они будут неактивны - необходимо быть осторожны относительно того, что Вы сделали бы. Но возвращаясь к исходному оператору - если Вы полагаете, что 1-й случай Ваше определение, нет никакого действительно простого способа сделать это. Необходимо было бы получить каждое сенсорное событие, проведя его на цепочке респондента по мере необходимости при замечании времени, это было получено. Это даст Вам некоторое основание для того, чтобы сделать неактивное вычисление. Если Вы полагаете, что второй случай Ваше определение, можно играть с уведомлением NSPostWhenIdle, чтобы попытаться выполнить логику в то время.

3
ответ дан wisequark 23 November 2019 в 22:10
поделиться

Эта цепочка мне очень помогла, и я заключил ее в подкласс UIWindow, который отправляет уведомления. Я выбрал уведомления, чтобы сделать их действительно слабой связью, но вы можете достаточно легко добавить делегата.

Вот суть:

http://gist.github.com/365998

Кроме того, причиной проблемы с подклассом UIApplication является то, что NIB настроен на создание двух объектов UIApplication, поскольку он содержит приложение. и делегат. Подкласс UIWindow работает отлично.

12
ответ дан 23 November 2019 в 22:10
поделиться

На самом деле Идея подкласса отлично работает. Просто не делайте своего делегата подклассом UIApplication. Создайте еще один файл, наследуемый от UIApplication (например, myApp). В IB установите класс объекта fileOwner на myApp, а в myApp.m реализуйте метод sendEvent, как указано выше. В main.m выполните:

int retVal = UIApplicationMain(argc,argv,@"myApp.m",@"myApp.m")

et voilà!

4
ответ дан 23 November 2019 в 22:10
поделиться