iphone - ¿Cómo cancelar una secuencia de eventos UITouch?
ios touchesmoved (12)
Esta solución puede ser un poco complicada, pero podría implementar y llamar manualmente
- (void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
Estoy basando esta solución libremente en algunos ajustes que hice a la aplicación de ejemplo MoveMe en el sitio de código de muestra de iPhone de Apple donde modifiqué el método touchesMoved
para que se vea así:
- (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;
}
Tengo una vista de UIImage
que responde a eventos táctiles. Quiero cancelar la secuencia táctil, es decir, otras llamadas a touchesMoved:
si el toque se sale de ciertos límites. ¿Cómo puedo hacer eso?
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 que pueda llamar para cancelar una secuencia táctil.
Recientemente me he enfrentado al mismo problema y encontré una forma estándar de 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.
Debes llamar a [super touchesMoved:withEvent:]
para dejar que la súper vista se limpie del evento, pero lo más importante es que no debes llamar a [super touchesCancelled:withEvent:]
.
Esto es lo que utilicé en una celda para evitar que se seleccionara cuando detecté un deslizamiento:
- (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];
}
}
No creo que sea posible porque no lo veo documentado y ninguna de estas soluciones funciona.
Puede verificar que las ubicaciones de los puntos de contacto estén en CGRect (es decir, que los puntos estén en 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];
}
}
En iOS5 parece haber un método privado en UITouch
-(void)setSentTouchesEnded:(BOOL)ended;
Según la implementación de Apple, podría dejar de enviar eventos
Otra forma de hacerlo sería usar objetos asociativos
- (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);
}
}
Intente establecer temporalmente la propiedad userInteractionEnabled de UIImageView a NO
Solo estaba tratando de resolver algo como esto, y descubrí que ninguna de las soluciones que ella mencionaba 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ó.
- Configurar una bandera booleana llamada "deshabilitada"
- En tocadoMoved, primero verifique que el toque esté dentro de la vista deseada. Si no es así, configure el indicador desactivado en SÍ.
- Aún en "Memorado" tocado, revisa la bandera antes de realizar tu acción. Entonces, en este punto, no pasará nada si están fuera de la vista.
- En toques Encendidos, establezca el indicador de desactivado en NO. Entonces, la secuencia táctil se detiene de forma efectiva hasta que el usuario levanta el dedo.
Supongo que esto funcionará para ti a menos que tengas una razón específica para necesitar literalmente la cancelación de la secuencia táctil.
La solución de "fuerza bruta" depende 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).
Puede crear una categoría para UITouch. Puedes declarar
@property (nonatomic,strong,readwrite) UIView *view;
Y cuando cambia touch.view a nil, por ejemplo, puede simular el fin de despachar eventos táctiles
Este código te ayudará. Desactivo el evento táctil en el método touchesMoved:
y estoy habilitando el evento táctil en touchesCancelled:
method
-(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];
}
Lo logro quitando la vista de su supervista y añadiéndola directamente 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.