2009-02-10 10 views
20

Tengo una vista UIImage que responde a eventos táctiles. Quiero cancelar la secuencia de toque, es decir, otras llamadas al touchesMoved:, si el toque se sale de ciertos límites. ¿Cómo puedo hacer eso?Cómo cancelar una secuencia de eventos UITouch?

Sé que en touchesMoved: puedo inspeccionar las coordenadas del objeto táctil e ignorarlo, pero lo que no sé es cómo cancelar la secuencia por completo. No veo ningún método documentado en el Apple Developer UIResponder Reference al que pueda llamar para cancelar una secuencia táctil.

Respuesta

6

Esta solución puede ser un poco kludgy, pero se puede implementar y llamar manualmente

- (void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event; 

estoy basando esta solución libremente en algunos ajustes que hice para la aplicación de ejemplo moveme en el sitio de Apple iPhone sample code donde he modificado el touchesMoved método para tener este aspecto:

- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 
    UITouch *touch = [touches anyObject]; 
    if ([touch view] == placardView) 
     CGPoint location = [touch locationInView:self]; 
     placardView.center = location; 
     // I added the following line: 
     [self touchesCancelled:touches withEvent:event]; 
     return; 
} 
+1

Gracias, intentaré esto cuando regrese a mi mac. ¿Pero esto va a cancelar los eventos de toques posteriores? Me parece que después de una llamada manual a touchesCancelled, el sistema llamará a touchesMoved. –

+0

Dentro de los límites del código de muestra MoveMe, cancelará el toque, pero creo que tiene razón, se llamará a touchesMoved. Cuanto más lo pienso, menos creo que Toques cancelados es la decisión correcta. –

+0

Eso no funciona y los eventos de "movimiento" siguen apareciendo. – Andy

2

he enfrentado el mismo problema hace poco y encontré una forma estándar para resolverlo. Puede usar [[UIApplication sharedApplication] beginIgnoringInteractionEvents] para dejar de entregar eventos touchesMoved a toda su aplicación. Asegúrese de habilitarlos utilizando [[UIApplication sharedApplication] endIgnoringInteractionEvents] cuando necesite volver a recibir toques.

3

es necesario llamar a [super touchesMoved:withEvent:] con el fin de permitir que el super vista a limpiar desde el evento pero lo más importante, es necesario no llamada [super touchesCancelled:withEvent:].

Esto es lo que he usado en una celda para evitar que se selecciona cuando detecté un golpe:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    if (!showingEdit) { 
     if (IS_FAR_ENOUGH_TO_BE_A_SWIPE) { 
      RESPOND_TO_SWIPE 
      showingEdit = YES; 
      [super touchesCancelled:touches withEvent:event]; 
     } else { 
      [super touchesMoved:touches withEvent:event]; 
     } 
    } 
} 

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    if (!showingEdit) { 
     [super touchesEnded:touches withEvent:event]; 
    } 
} 
+1

Esto no funcionó para mí. – ma11hew28

2

no creo que es posible porque yo no lo veo documentado y ninguna de estas soluciones trabajo.

-2

Puede verificar que las ubicaciones del punto de contacto están en CGRect (es decir, los puntos están en el rectángulo de su imagen) o no. Si no están en ese Rect, el toque será cancelado.

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
UITouch *touch = [touches anyObject]; 
CGPoint touchLocation = [touch locationInView:self.view]; 

    if (CGRectContainsPoint(myImageView, touchLocation)) 
    { 
     lastPoint = [touch locationInView: myImageView]; 
    } 

    NSLog(@"Last :%.2f - %.2f",lastPoint.x, lastPoint.y); 
    } 

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    CGPoint currentPoint; 
    UITouch *touch = [touches anyObject]; 
    CGPoint touchLocation = [touch locationInView:self.view]; 

    if (CGRectContainsPoint(myImageView.frame, touchLocation)) 
    { 
     currentPoint = [touch locationInView: myImageView]; 
    } 
} 
+1

Ese código no cancela más llamadas a 'touchesMoved:'. Simplemente los ignora. – ma11hew28

0

En IOS5 parece que hay un método privado en UITouch

-(void)setSentTouchesEnded:(BOOL)ended; 

Dependiendo de la aplicación de Apple que podría detener el envío de eventos

Otra forma de hacerlo sería utilizando objetos asociativo

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    if ([(NSNumber *)objc_getAssociatedObject(touch, &outKey) boolValue]) 
     return; 
    if (sometouchisoutsideofview) { 
     objc_setAssociatedObject(touch, &outKey, [NSNumber numberWithBool:YES], OBJC_ASSOCIATION_RETAIN); 
    } 
} 
3

Probar la configuración temporal del usuario de UIImageViewInteracción Propiedad habilitada para NO

0

Solo intentaba resolver algo como esto, y descubrí que ninguna de las soluciones enumeradas para ella funcionaba para mí. Lo mejor que pude hacer fue ignorar temporalmente los toques, pero luego se reanudaron cuando el toque volvió a entrar en la vista.

Finalmente lo resolvió.

  1. Establecer un indicador booleano llamado "desactivado"
  2. En touchedMoved, compruebe primero que el contacto está dentro de la vista deseada. Si no es así, configure el indicador desactivado en SÍ.
  3. Aún en inmovilizado, verifique la bandera antes de realizar su acción. Entonces, en este punto, no pasará nada si están fuera de la vista.
  4. En toquesEnded, establezca el indicador deshabilitado en NO. Entonces, la secuencia táctil se detiene de forma efectiva hasta que el usuario levanta el dedo.

Supongo que esto funcionará para usted a menos que tenga una razón específica para necesitar literalmente la secuencia táctil cancelada.

+0

Incluso puede hacer el seguimiento al estilo UIControl utilizando un solo indicador. Lo cual se siente más natural que si toda la secuencia del evento se cancelara a la vez. – Andy

1

Solución de "fuerza bruta" dependiendo de si satisface sus necesidades: elimine y vuelva a inicializar la subvista que recibe los toques o responde a ellos (por supuesto, cuide el marco y el contenido).

-1

Puede crear una categoría para UITouch. Se puede declarar

@property (nonatomic,strong,readwrite) UIView *view; 

Y cuando se cambia touch.view a cero, por ejemplo, se puede simular fin de enviar eventos táctiles

1

Este código le ayudará. Desactivo eventos táctiles en touchesMoved: método y estoy permitiendo a eventos táctiles en touchesCancelled: método

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    UITouch *touch = [touches anyObject]; 
    ....... 
    ....... 
    Your code 
    ....... 
    ....... 

    //Condition when you want to disable touch event 

    [[UIApplication sharedApplication] beginIgnoringInteractionEvents]; 

    ....... 
    ....... 
    Your code 
    ....... 
    ....... 
} 


- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    [[UIApplication sharedApplication] endIgnoringInteractionEvents]; 
} 
+0

Esto no funcionó para mí. – avance

1

puedo lograr esto mediante la eliminación de la vista desde su supervista y la adición de él hacia atrás.

[view retain]; 
UIView *sv = view.superview; 
[view removeFromSuperview]; 
[sv addSubview:view]; 
[view release]; 

Esto rompe la cadena de respuesta a la vista por lo que los toques restantes no se recibirán en la vista. El siguiente toque aún se recibirá de forma normal.

Cuestiones relacionadas