Кто-нибудь реализовал функцию, при которой, если пользователь не касался экрана в течение определенного периода времени, вы предпринимаете определенные действия? Я пытаюсь найти лучший способ сделать это.
В UIApplication есть несколько похожий метод:
[UIApplication sharedApplication].idleTimerDisabled;
Было бы неплохо, если бы у вас было что-то вроде этого:
NSTimeInterval timeElapsed = [UIApplication sharedApplication].idleTimeElapsed;
Затем я мог бы установить таймер и периодически проверять это значение и предпринимать некоторые действия, когда оно превышает пороговое значение.
Надеюсь, это объясняет, что я ищу. Кто-нибудь уже занимался этой проблемой, или есть мысли о том, как бы вы это сделали? Спасибо.
ios
objective-c
iphone
idle-timer
Майк МакМастер
источник
источник
Ответы:
Вот ответ, который я искал:
Пусть ваше приложение делегирует подкласс UIApplication. В файле реализации переопределите метод sendEvent: следующим образом:
где maxIdleTime и idleTimer являются переменными экземпляра.
Для того чтобы это работало, вам также нужно изменить main.m, чтобы указать UIApplicationMain использовать ваш класс делегата (в этом примере AppDelegate) в качестве основного класса:
источник
NSTimer
случаев, если есть много касаний.У меня есть вариант решения таймера простоя, который не требует создания подклассов UIApplication. Он работает с определенным подклассом UIViewController, поэтому он полезен, если у вас есть только один контроллер представления (например, интерактивное приложение или игра) или вы хотите обрабатывать время простоя только в конкретном контроллере представления.
Он также не создает заново объект NSTimer при каждом сбросе таймера простоя. Он только создает новый, если таймер срабатывает.
Ваш код может вызывать
resetIdleTimer
любые другие события, которые могут потребовать аннулирования таймера простоя (например, значительный ввод акселерометра).(Код очистки памяти исключен для краткости.)
источник
Для Swift v 3.1
не забудьте прокомментировать эту строку в AppDelegate // @ UIApplicationMain
Наблюдение за уведомлением в любом другом классе
источник
if idleTimer != nil
вsendEvent()
методе?timeoutInSeconds
ответа веб-службы?Этот поток очень помог, и я поместил его в подкласс UIWindow, который отправляет уведомления. Я выбрал уведомления, чтобы сделать их по-настоящему слабой связью, но вы можете легко добавить делегата.
Вот суть:
http://gist.github.com/365998
Кроме того, причина проблемы подкласса UIApplication заключается в том, что NIB настроен на создание 2 объектов UIApplication, поскольку он содержит приложение и делегат. Подкласс UIWindow прекрасно работает, хотя.
источник
На самом деле идея создания подклассов прекрасно работает. Только не делайте своего делегата
UIApplication
подклассом. Создайте другой файл, который наследуется отUIApplication
(например, myApp). В IB установите классfileOwner
объектаmyApp
и в myApp.m реализуйтеsendEvent
метод, как указано выше. В main.m сделать:и вуаля!
источник
Я только что столкнулся с этой проблемой в игре, которая управляется движениями, т.е. блокировка экрана отключена, но я должен снова включить ее в режиме меню. Вместо таймера я инкапсулировал все вызовы
setIdleTimerDisabled
внутри небольшого класса, предоставив следующие методы:disableIdleTimer
отключает таймер простоя,enableIdleTimerDelayed
при входе в меню или что-либо еще должно работать с активным таймером простоя иenableIdleTimer
вызывается изapplicationWillResignActive
метода вашего AppDelegate, чтобы гарантировать, что все ваши изменения сброшены должным образом к поведению системы по умолчанию.Я написал статью и предоставил код для одиночного класса IdleTimerManager Обработка таймера простоя в играх iPhone
источник
Вот еще один способ обнаружения активности:
Таймер добавлен
UITrackingRunLoopMode
, поэтому он может срабатывать только при наличииUITracking
активности. Это также имеет приятное преимущество - не спамить вас на всех событиях касания, таким образом, информируя, если была активность в последниеACTIVITY_DETECT_TIMER_RESOLUTION
секунды. Я назвал селектор,keepAlive
поскольку это кажется подходящим вариантом использования для этого. Разумеется, вы можете делать все, что пожелаете, с информацией о том, что было в последнее времяисточник
В конечном итоге вам нужно определить, что вы считаете бездействующим - является ли бездействие результатом того, что пользователь не касается экрана, или это состояние системы, если не используются вычислительные ресурсы? Во многих приложениях пользователь может что-то делать, даже если он не взаимодействует с устройством через сенсорный экран. Хотя пользователь, вероятно, знаком с концепцией перехода устройства в режим сна и замечанием того, что это произойдет с помощью затемнения экрана, он не обязательно ожидает, что что-то произойдет, если он находится в режиме ожидания - вам нужно быть осторожным о том, что вы будете делать. Но вернемся к первоначальному утверждению - если вы считаете, что ваш первый случай является вашим определением, то не существует простого способа сделать это. Вам нужно будет получать каждое сенсорное событие, передавая его по цепочке респондента по мере необходимости, отмечая время его получения. Это даст вам некоторую основу для расчета простоя. Если вы рассматриваете второй случай как свое определение, вы можете поиграть с уведомлением NSPostWhenIdle, чтобы попытаться выполнить свою логику в это время.
источник
Есть способ сделать это приложение широким без необходимости делать что-либо для отдельных контроллеров. Просто добавьте распознаватель жестов, который не отменяет прикосновения. Таким образом, все прикосновения будут отслеживаться по таймеру, а другие прикосновения и жесты не будут затронуты вообще, поэтому никто не должен знать об этом.
В вашем приложении делегат завершил запуск метода, просто вызовите addGesture, и все готово. Все касания будут проходить через методы CatchAllGesture, не мешая функционированию других.
источник
-sendEvent:
является излишним, иUITrackingRunLoopMode
не обрабатывает много случаев.