¿Alguien ha implementado una función en la que si el usuario no ha tocado la pantalla durante un cierto período de tiempo, usted toma una determinada acción? Estoy tratando de encontrar la mejor manera de hacerlo.
Existe este método algo relacionado en UIApplication:
[UIApplication sharedApplication].idleTimerDisabled;
Sería bueno si tuvieras algo como esto:
NSTimeInterval timeElapsed = [UIApplication sharedApplication].idleTimeElapsed;
Entonces podría configurar un temporizador y verificar periódicamente este valor, y tomar alguna acción cuando exceda un umbral.
Espero que eso explique lo que estoy buscando. ¿Alguien ha abordado este problema o tiene alguna idea sobre cómo lo haría? Gracias.
ios
objective-c
iphone
idle-timer
Mike McMaster
fuente
fuente
Respuestas:
Aquí está la respuesta que había estado buscando:
Haga que su aplicación delegue la subclase UIApplication. En el archivo de implementación, anule el método sendEvent: así:
donde maxIdleTime e idleTimer son variables de instancia.
Para que esto funcione, también debe modificar su main.m para decirle a UIApplicationMain que use su clase delegada (en este ejemplo, AppDelegate) como la clase principal:
fuente
NSTimer
instancias si hay muchos toques.Tengo una variación de la solución de temporizador inactivo que no requiere subclasificar la aplicación UIA. Funciona en una subclase específica de UIViewController, por lo que es útil si solo tiene un controlador de vista (como puede tener una aplicación o juego interactivo) o si solo desea manejar el tiempo de espera inactivo en un controlador de vista específico.
Tampoco vuelve a crear el objeto NSTimer cada vez que se reinicia el temporizador inactivo. Solo crea uno nuevo si se dispara el temporizador.
Su código puede llamar
resetIdleTimer
a cualquier otro evento que pueda necesitar invalidar el temporizador inactivo (como una entrada significativa del acelerómetro).(código de limpieza de memoria excluido por brevedad).
fuente
Para swift v 3.1
no olvides comentar esta línea en AppDelegate // @ UIApplicationMain
Observación de notificaciones en cualquier otra clase
fuente
if idleTimer != nil
en elsendEvent()
método?timeoutInSeconds
de la respuesta del servicio web?Este hilo fue de gran ayuda, y lo envolví en una subclase de UIWindow que envía notificaciones. Elegí notificaciones para que sea un acoplamiento realmente flojo, pero puedes agregar un delegado con bastante facilidad.
Aquí está la esencia:
http://gist.github.com/365998
Además, la razón del problema de la subclase UIApplication es que la NIB está configurada para luego crear 2 objetos UIApplication ya que contiene la aplicación y el delegado. Sin embargo, la subclase UIWindow funciona muy bien.
fuente
En realidad, la idea de subclases funciona muy bien. Simplemente no hagas que tu delegado sea la
UIApplication
subclase. Cree otro archivo que herede deUIApplication
(por ejemplo, myApp). En IB, establezca la clase delfileOwner
objeto enmyApp
y en myApp.m implemente elsendEvent
método como se indica arriba. En main.m do:et voilà!
fuente
Acabo de encontrarme con este problema con un juego que está controlado por movimientos, es decir, tiene el bloqueo de pantalla deshabilitado pero debería habilitarlo nuevamente cuando esté en el modo de menú. En lugar de un temporizador, encapsulé todas las llamadas
setIdleTimerDisabled
dentro de una clase pequeña proporcionando los siguientes métodos:disableIdleTimer
desactiva el temporizador inactivo,enableIdleTimerDelayed
al ingresar al menú o lo que sea que se ejecute con el temporizador inactivo activo yenableIdleTimer
se llama desde elapplicationWillResignActive
método de AppDelegate para garantizar que todos los cambios se restablezcan correctamente al comportamiento predeterminado del sistema.Escribí un artículo y proporcioné el código para la clase de singleton IdleTimerManager Idle Timer Handling en juegos de iPhone
fuente
Aquí hay otra forma de detectar actividad:
Se agrega el temporizador
UITrackingRunLoopMode
, por lo que solo puede disparar si hayUITracking
actividad. También tiene la ventaja de no enviarle correos no deseados para todos los eventos táctiles, informando así si hubo actividad en los últimosACTIVITY_DETECT_TIMER_RESOLUTION
segundos. Llamé al selectorkeepAlive
ya que parece un caso de uso apropiado para esto. Por supuesto, puede hacer lo que desee con la información de que hubo actividad recientemente.fuente
En última instancia, debe definir lo que considera inactivo: ¿está inactivo el resultado de que el usuario no toca la pantalla o es el estado del sistema si no se utilizan recursos informáticos? Es posible, en muchas aplicaciones, que el usuario haga algo incluso si no interactúa activamente con el dispositivo a través de la pantalla táctil. Si bien el usuario probablemente esté familiarizado con el concepto de que el dispositivo se va a dormir y el aviso de que sucederá a través de la atenuación de la pantalla, no es necesariamente el caso de que esperen que ocurra algo si están inactivos; debe tener cuidado sobre lo que harías Pero volviendo a la declaración original: si considera que el primer caso es su definición, no hay una manera realmente fácil de hacerlo. Debería recibir cada evento táctil, pasarlo a lo largo de la cadena de respuesta según sea necesario, al tiempo que señala la hora en que se recibió. Eso le dará alguna base para hacer el cálculo inactivo. Si considera que el segundo caso es su definición, puede jugar con una notificación NSPostWhenIdle para intentar realizar su lógica en ese momento.
fuente
Hay una manera de hacer esta aplicación de manera amplia sin que los controladores individuales tengan que hacer nada. Simplemente agregue un reconocedor de gestos que no cancele toques. De esta manera, todos los toques se rastrearán para el temporizador, y otros toques y gestos no se verán afectados en absoluto, por lo que nadie más tiene que saberlo.
En el delegado de su aplicación, terminó el método de inicio, simplemente llame a addGesture y ya está todo listo. Todos los toques pasarán por los métodos de CatchAllGesture sin que esto impida la funcionalidad de otros.
fuente
-sendEvent:
es exagerada yUITrackingRunLoopMode
no maneja muchos casos.