2011-12-09 23 views
18

¿Es posible escuchar y captar de alguna manera todos los eventos táctiles que ocurren en una aplicación?Escuche todos los eventos táctiles en una aplicación para iOS

La aplicación que estoy desarrollando actualmente se usará en salas de exposición y quioscos de información y, por lo tanto, me gustaría volver a la sección de inicio de la aplicación si no se han recibido toques durante un par de minutos. Una especie de funcionalidad de protector de pantalla, si se quiere. Estoy planeando implementar esto teniendo un temporizador ejecutándose en segundo plano, que debe reiniciarse y reiniciarse cada vez que ocurra un evento táctil en algún lugar de la aplicación. ¿Pero cómo puedo escuchar los eventos táctiles? Alguna idea o sugerencia?

Respuesta

31

Es realmente fácil.

Necesita una subclase de UIApplication (llamémosla MyApplication).

modificar su main.m utilizarlo:

 

return UIApplicationMain(argc, argv, @"MyApplication", @"MyApplicationDelegate"); 
 

Y reemplaza el método [MyApplication sendEvent:]:

 

- (void)sendEvent:(UIEvent*)event { 
    //handle the event (you will probably just reset a timer) 

    [super sendEvent:event]; 
} 
 
+0

El tamaño abajo de esto es que no podemos hacer esto en tiempo de ejecución. ¿Alguna otra solución? – Legoless

+0

cómo saber cuál fue? –

+0

@AsadullahAli Consulte la documentación de 'UIEvent' (https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UIEvent_Class/index.html). Cada evento tiene un tipo, un subtipo y también un conjunto de toques que puedes inspeccionar. – Sulthan

1

Se puede poner una visión transparente en la parte superior de la jerarquía de la vista, y elegir en que ver si manejar los eventos táctiles que recibe o pasarlos a las vistas más bajas.

+0

Eso solo funcionará para una aplicación que solo muestre una vista. Se rompe, por ejemplo, tan pronto como presente otro controlador de vista. – DarkDust

+0

No si usted crea las vistas correctamente. –

+1

Bueno, un 'presentModalViewController: animado:' oscurecería su vista o ¿me falta algo? ¿O está sugiriendo que se inserte la vista transparente en cada controlador de vista? Eso sin duda sería mucho trabajo y frágil, ya que siempre debes asegurarte de no poner accidentalmente una vista sobre él. ¿O hay una manera fácil de asegurar esto? – DarkDust

3

Se podría utilizar una subclase de UIWindow, anulando hitTest:. Luego, en el XIB de su ventana principal, hay un objeto que simplemente se llama simplemente Window. Haga clic en eso, luego a la derecha en el panel de Utilidades vaya a Identidades (Alt-Command-3). En el campo de texto Clase, ingrese el nombre de su subclase UIWindow.

MyWindow.h

@interface MyWindow : UIWindow 
@end 

MyWindow.m

@implementation MyWindow 

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event 
{ 
    UIView *res; 

    res = [super hitTest:point withEvent:event]; 

    // Setup/reset your timer or whatever your want to do. 
    // This method will be called for every touch down, 
    // but not for subsequent events like swiping/dragging. 
    // Still, might be good enough if you want to measure 
    // in minutes. 

    return res; 
} 

@end 
+0

El problema aquí es que no obtienes ninguna información cuando toques fin. – Legoless

2

Puede utilizar un reconocedor del grifo para este gesto. Subclase UITapGestureRecognizer e importe <UIKit/UIGestureRecognizerSubclass.h>. Esto define touchesBegan:, touchesMoved:, touchesEnded: y touchesCancelled:. Pon tu código de manejo táctil en los métodos apropiados.

Crea una instancia del reconocedor de gestos en application:didFinishLaunchingWithOptions: y añádelo al UIWindow. Establezca cancelsTouchesInView en NO y pasará todos los toques de forma transparente.

Crédito: this post.

3

crear una clase "VApplication" que se extiende desde UIApplication y pegar estos código para la clase correspondiente

VApplication.h

#import <Foundation/Foundation.h> 

// # of minutes before application times out 
#define kApplicationTimeoutInMinutes 10 

// Notification that gets sent when the timeout occurs 
#define kApplicationDidTimeoutNotification @"ApplicationDidTimeout" 

/** 
* This is a subclass of UIApplication with the sendEvent: method 
* overridden in order to catch all touch events. 
*/ 

@interface VApplication : UIApplication 
{ 
    NSTimer *_idleTimer; 
} 

/** 
* Resets the idle timer to its initial state. This method gets called 
* every time there is a touch on the screen. It should also be called 
* when the user correctly enters their pin to access the application. 
*/ 
- (void)resetIdleTimer; 

@end 

VApplication.m

#import "VApplication.h" 
#import "AppDelegate.h" 

@implementation VApplication 

- (void)sendEvent:(UIEvent *)event 
{ 
    [super sendEvent:event]; 
    // Fire up the timer upon first event 
    if(!_idleTimer) { 
     [self resetIdleTimer]; 
    } 

    // Check to see if there was a touch event 
    NSSet *allTouches  = [event allTouches]; 

    if ([allTouches count] > 0) 
     { 
     UITouchPhase phase = ((UITouch *)[allTouches anyObject]).phase; 
     if (phase == UITouchPhaseBegan) 
      { 
      [self resetIdleTimer];   
      } 
     } 
} 

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

    // Schedule a timer to fire in kApplicationTimeoutInMinutes * 60 


// int timeout = [AppDelegate getInstance].m_iInactivityTime; 
    int timeout = 3; 
    _idleTimer = [NSTimer scheduledTimerWithTimeInterval:timeout 
                target:self 
               selector:@selector(idleTimerExceeded) 
               userInfo:nil 
               repeats:NO]; 

} 

- (void)idleTimerExceeded 
{ 
    /* Post a notification so anyone who subscribes to it can be notified when 
    * the application times out */ 


    [[NSNotificationCenter defaultCenter] 
    postNotificationName:kApplicationDidTimeoutNotification object:nil]; 
} 


@end 

reemplazar el nombre de clase "VApplication" en nuestro

Main.m

archivo así

int main(int argc, char * argv[]) 
{ 
    @autoreleasepool { 
     return UIApplicationMain(argc, argv, @"VApplication", NSStringFromClass([AppDelegate class])); 

    } 
} 

Registrar la notificación correspondiente para su ver controlador

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidTimeout:) name:kApplicationDidTimeoutNotification object:nil]; 

Y una vez que el tiempo de espera ocurra la notificación se disparará y manejar el evento como este

- (void) applicationDidTimeout:(NSNotification *) notif //inactivity lead to any progress 
{ 


} 
+0

Gracias, necesitaba usar esto, ya que UITapGestureRecognizer no captaba todos los eventos táctiles por mí. – Pellet

Cuestiones relacionadas