iOS pierde los toques?

No encuentro nada para explicar los events perdidos de UITouch. Si aplastas tu mano completa en la pantalla lo suficiente, el número de toques de Borde será diferente al número de toques. Creo que la única manera de saber realmente sobre estos toques huérfanos será hacer reference a ellos mismos y hacer un seguimiento de cuánto time no se han movido.

Código de muestra:

int touchesStarted = 0; int touchesFinished = 0; - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { touchesStarted += touches.count; } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { touchesFinished += touches.count; NSLog(@"%d / %d", touchesStarted, touchesFinished); } - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { [self touchesEnded:touches withEvent:event]; } 

No olvide los touchesCancelled : reference de UESponders

Edición en respuesta a la actualización del póster:

Cada object táctil proporciona en qué fase se encuentra:

 typedef enum { UITouchPhaseBegan, UITouchPhaseMoved, UITouchPhaseStationary, UITouchPhaseEnded, UITouchPhaseCancelled, } UITouchPhase; 

Creo que si un toque comienza y termina en el mismo set de events táctiles, -touchesBegan:withEvent: será llamado pero contendrá toques que han finalizado o cancelado .

Debería cambiar su código de conteo para que se vea así:

 int touchesStarted = 0; int touchesFinished = 0; - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [self customTouchHandler:touches]; } - (void)touchesEnded:(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); } 

Cada evento táctil solo pasará por las dos fases de inicio y finalización / cancelación, por lo que su count debe coincidir tan pronto como sus dedos estén fuera de la pantalla.

Una cosa para recordar … Puede recibir algunos toques que tengan múltiples toques. No te olvides de tomar tapCount en count.

Sin embargo, si todavía tiene el problema, puede considerar todos los toques del evento, aunque presenta algunos otros problemas de gestión …

HACK ALERT

He codificado el siguiente HACK para solucionarlo . A veces, los toques seleccionados no se llaman, PERO, los toques aparecen como parte de todos los toques en el evento.

Tenga en count que ahora puede procesar el mismo toque "cancelado" o "finalizado" varias veces. Si ese es un problema, debe mantener su propio estado de "pendientes", y eliminarlos cuando haya terminado.

Sí, todo está bastante mal, pero no sé cómo superar este problema sin un truco similar. La solución básica es mirar todos los toques en cada evento y procesarlos en function de su fase, llamando a la opción finalizada / cancelada cuando se ven.

 - (void) touchesEndedOrCancelled:(NSSet *)touches { __block NSMutableSet *ended = nil; __block NSMutableSet *canceled = nil; [touches enumerateObjectsUsingBlock:^(UITouch *touch, BOOL *stop) { if (touch.phase == UITouchPhaseEnded) { if (!ended) ended = [NSSet setWithObject:touch]; else [ended addObject:touch]; } else if (touch.phase == UITouchPhaseCancelled) { if (!canceled) canceled = [NSSet setWithObject:touch]; else [canceled addObject:touch]; } }]; if (ended) [self touchesEnded:ended withEvent:nil]; if (canceled) [self touchesCancelled:canceled withEvent:nil]; } 

Luego, llámala al final de toquesBegan y tocaMovido …

 [self touchesEndedOrCancelled:event.allTouches]; 

Para que esto funcione, touchesEnded / Canceled no debe ahogarse en ningún evento. Además, el "otro" necesita ser manejado. En los tactos indicados …

 [self touchesCancelled:[event.allTouches objectsPassingTest:^BOOL(UITouch *touch, BOOL *stop) { return touch.phase == UITouchPhaseCancelled; }] withEvent:nil]; 

y en toques cancelado …

 [self touchesEnded:[event.allTouches objectsPassingTest:^BOOL(UITouch *touch, BOOL *stop) { return touch.phase == UITouchPhaseEnded; }] withEvent:nil]; 

Es posible que deba proporcionar más detalles pero …

Si desliza el dedo por el borde de la pantalla, este evento mostrará que el tacto comenzó y se tocó movido, pero sin final, ya que en realidad no terminó (levante el dedo). Este podría ser su problema, que el evento no sucedió. Además, hay un límite para la cantidad de toques en multitáctil si presiona decir 10 veces su hasta el sistema para determinar qué events son realmente y cuáles son falsos, parece que está utilizando el hardware incorrectamente.