tab icon guidelines buttons bar ios objective-c sprite-kit uitouch
https://www.dropbox.com/s/qmgxka1gtgwquio/TapTest.zip

ios - icon - Una cuenta de toques iniciados no es igual a la cuenta de toques terminados



status bar ios (5)

No puedo comentar, así que responderé aquí. Usted puede imprimir todos los manejadores de esta manera, tal vez ayude:

- (void)customTouchHandler:(NSSet *)touches { static int handlerCounter = 0; handlerCounter++; for(UITouch* touch in touches){ NSLog(@"%d: %d", handlerCounter, touch.phase); if(touch.phase == UITouchPhaseBegan) touchesStarted++; if(touch.phase == UITouchPhaseEnded || touch.phase == UITouchPhaseCancelled) touchesFinished++; } NSLog(@"%d / %d", touchesStarted, touchesFinished); }

¿Es posible cambiar (touch.phase) en obj-c? Si el "o" está en el segundo si se evalúa correctamente, intente usar corchetes.

Tengo el siguiente código para propósitos de prueba:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [self customTouchHandler:touches]; } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { [self customTouchHandler:touches]; } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { [self customTouchHandler:touches]; } - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { [self customTouchHandler:touches]; } - (void)customTouchHandler:(NSSet *)touches { for(UITouch* touch in touches){ if(touch.phase == UITouchPhaseBegan) touchesStarted++; if(touch.phase == UITouchPhaseEnded || touch.phase == UITouchPhaseCancelled) touchesFinished++; } NSLog(@"%d / %d", touchesStarted, touchesFinished); }

Supongo que cuando no hay ningún toque en la pantalla, los touchesStarted deberían ser siempre iguales a los touchesFinished , pero tengo un resultado bastante extraño:

2014-04-16 13:44:27.780 App[5925:60b] 2 / 0 2014-04-16 13:44:27.911 App[5925:60b] 2 / 1

Presioné la pantalla con dos dedos y luego los solté casi (pero no) al mismo tiempo.

¿Me estoy perdiendo de algo? Varios toques habilitados para mi vista. Por cierto, la vista es SKView y el código pertenece a mi SKScene personalizado.

ACTUALIZAR

Como muchos de ustedes no pueden reproducir este extraño comportamiento, preparé un ejemplo de proyecto de Xcode: https://www.dropbox.com/s/qmgxka1gtgwquio/TapTest.zip

Intenta hacer tapping con dos dedos al mismo tiempo muchas veces. touchesStarted deben ser iguales a los touchesEnded cuando se quitan los dedos, ¿verdad? Pero no lo son. Aquí está mi salida:

2014-04-24 12:49:06.359 TapTest[8207:60b] 1 / 0 2014-04-24 12:49:06.376 TapTest[8207:60b] 2 / 0 2014-04-24 12:49:06.458 TapTest[8207:60b] 2 / 0 2014-04-24 12:49:06.460 TapTest[8207:60b] 2 / 1 2014-04-24 12:49:06.491 TapTest[8207:60b] 2 / 2 2014-04-24 12:49:07.325 TapTest[8207:60b] 3 / 2 2014-04-24 12:49:07.342 TapTest[8207:60b] 4 / 2 2014-04-24 12:49:07.408 TapTest[8207:60b] 4 / 2 2014-04-24 12:49:07.410 TapTest[8207:60b] 4 / 3 2014-04-24 12:49:07.426 TapTest[8207:60b] 4 / 3 2014-04-24 12:49:07.441 TapTest[8207:60b] 4 / 4 2014-04-24 12:49:07.842 TapTest[8207:60b] 6 / 4 2014-04-24 12:49:07.925 TapTest[8207:60b] 6 / 4 2014-04-24 12:49:07.941 TapTest[8207:60b] 6 / 5 2014-04-24 12:49:08.042 TapTest[8207:60b] 8 / 5 2014-04-24 12:49:08.125 TapTest[8207:60b] 8 / 6 2014-04-24 12:49:08.259 TapTest[8207:60b] 9 / 6 2014-04-24 12:49:08.293 TapTest[8207:60b] 9 / 6 2014-04-24 12:49:08.308 TapTest[8207:60b] 9 / 7 2014-04-24 12:49:08.425 TapTest[8207:60b] 10 / 7 2014-04-24 12:49:08.442 TapTest[8207:60b] 11 / 7 2014-04-24 12:49:08.444 TapTest[8207:60b] 11 / 7 2014-04-24 12:49:08.492 TapTest[8207:60b] 11 / 8 2014-04-24 12:49:08.575 TapTest[8207:60b] 11 / 9 2014-04-24 12:49:08.642 TapTest[8207:60b] 12 / 9 2014-04-24 12:49:08.659 TapTest[8207:60b] 13 / 9 2014-04-24 12:49:08.660 TapTest[8207:60b] 13 / 9 2014-04-24 12:49:08.692 TapTest[8207:60b] 13 / 9 2014-04-24 12:49:08.694 TapTest[8207:60b] 13 / 10 2014-04-24 12:49:08.708 TapTest[8207:60b] 13 / 10 2014-04-24 12:49:08.741 TapTest[8207:60b] 13 / 11 2014-04-24 12:49:08.792 TapTest[8207:60b] 14 / 11 2014-04-24 12:49:08.809 TapTest[8207:60b] 15 / 11 2014-04-24 12:49:08.810 TapTest[8207:60b] 15 / 11 2014-04-24 12:49:08.890 TapTest[8207:60b] 15 / 11 2014-04-24 12:49:08.892 TapTest[8207:60b] 15 / 12 2014-04-24 12:49:08.908 TapTest[8207:60b] 15 / 13 2014-04-24 12:49:09.042 TapTest[8207:60b] 17 / 13 2014-04-24 12:49:09.141 TapTest[8207:60b] 17 / 14 2014-04-24 12:49:09.242 TapTest[8207:60b] 19 / 14 2014-04-24 12:49:09.341 TapTest[8207:60b] 19 / 14 2014-04-24 12:49:09.358 TapTest[8207:60b] 19 / 15 2014-04-24 12:49:09.441 TapTest[8207:60b] 21 / 15 2014-04-24 12:49:09.525 TapTest[8207:60b] 21 / 15 2014-04-24 12:49:09.542 TapTest[8207:60b] 21 / 15 2014-04-24 12:49:09.559 TapTest[8207:60b] 21 / 16 2014-04-24 12:49:09.608 TapTest[8207:60b] 22 / 16 2014-04-24 12:49:09.625 TapTest[8207:60b] 23 / 16 2014-04-24 12:49:09.626 TapTest[8207:60b] 23 / 16 2014-04-24 12:49:09.708 TapTest[8207:60b] 23 / 16 2014-04-24 12:49:09.709 TapTest[8207:60b] 23 / 17 2014-04-24 12:49:09.774 TapTest[8207:60b] 23 / 18 2014-04-24 12:49:09.810 TapTest[8207:60b] 24 / 18 2014-04-24 12:49:09.826 TapTest[8207:60b] 25 / 18 2014-04-24 12:49:09.828 TapTest[8207:60b] 25 / 18 2014-04-24 12:49:09.908 TapTest[8207:60b] 25 / 18 2014-04-24 12:49:09.909 TapTest[8207:60b] 25 / 19 2014-04-24 12:49:09.974 TapTest[8207:60b] 25 / 20 2014-04-24 12:49:09.992 TapTest[8207:60b] 26 / 20 2014-04-24 12:49:10.026 TapTest[8207:60b] 27 / 20 2014-04-24 12:49:10.027 TapTest[8207:60b] 27 / 20 2014-04-24 12:49:10.091 TapTest[8207:60b] 27 / 20 2014-04-24 12:49:10.094 TapTest[8207:60b] 27 / 21 2014-04-24 12:49:10.125 TapTest[8207:60b] 27 / 22


Parece que esto es un error en el método touchesBegan: . Por lo que puedo decir, Apple está utilizando un diccionario para asociar cada UITouch con el objeto al que se deben reenviar los métodos táctiles. De mis pruebas, parece que si hay varios toques que comienzan al mismo tiempo, solo uno de los toques se agrega al diccionario. Como resultado, su escena nunca recibirá las llamadas de método relacionadas con el toque para los otros toques, por lo que está viendo la diferencia entre los toques iniciados y los toques terminados.

Si subclasifica SKView y anula el método touchesBegan: , su escena debería recibir las llamadas correctas.

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { for (UITouch *touch in touches) { NSSet *newSet = [NSSet setWithObject:touch]; [super touchesBegan:newSet withEvent:event]; } }

Esto solucionó el problema para mí, pero es posible que haya algunos efectos secundarios al llamar al súper método varias veces.


Si está utilizando más de un dedo, debe incluir self.view.multipleTouchEnabled = YES; en tu init .

Realicé algunas pruebas exhaustivas en su código suministrado y la única vez que los números no coinciden es cuando la grabación se produce muy rápido a partir de una combinación de uno o ambos dedos. En este caso, iOS pierde el seguimiento del contacto con el estado actual.

Esto es muy similar a cuando un sprite rebota hacia arriba y hacia abajo muy rápidamente en otro sprite que a veces causa un estado de contacto incorrecto en el contacto de inicio.

Actualmente no hay forma de que puedas evitar esto con múltiples toques. Si usa un solo toque, su conteo siempre coincidirá (al menos en mis pruebas).


También tiene este problema.

La única solución que encontré en este momento basada en la observación de la fase táctil:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { NSLog(@"Began %lu of %lu", [touches count], [event.allTouches count]); for (UITouch *touch in touches) { [touch addObserver:self forKeyPath:@"phase" options:0 context:nil]; } } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { NSLog(@"Ended %lu of %lu", [touches count], [event.allTouches count]); } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if ([object isKindOfClass:[UITouch class]]) { UITouch *touch = object; NSLog(@"Touch %lu phase: %ld", (unsigned long)[touch hash], [touch phase]); if (touch.phase == UITouchPhaseEnded || touch.phase == UITouchPhaseCancelled) { NSLog(@"Touch %lu ended", (unsigned long)[touch hash]); [touch removeObserver:self forKeyPath:@"phase"]; } } }


Tuve este mismo problema antes ( touchesEnded: withEvent: no se llama ).

Mis pruebas revelaron que TouchEnded no se llamaba el 100% del tiempo. Mi solución: coloque los cuatro métodos de manejo táctil en el archivo AppDelegate.m y reenvíe los toques a su controlador de vista. No tengo idea de por qué funciona esto, pero no tuve ningún problema después de hacer eso.