iphone uitableview multi-touch pinch

iphone - Observando gestos multitáctiles de pellizco en un UITableView



uitableview swift 3 (2)

Este parece ser un problema clásico. En mi caso, quería interceptar algunos eventos a través de un UIWebView que no puede ser subclasificado, etc. etc.

Descubrí que la mejor manera de hacerlo es interceptar los eventos utilizando la ventana UI:

EventInterceptWindow.h

@protocol EventInterceptWindowDelegate - (BOOL)interceptEvent:(UIEvent *)event; // return YES if event handled @end @interface EventInterceptWindow : UIWindow { // It would appear that using the variable name ''delegate'' in any UI Kit // subclass is a really bad idea because it can occlude the same name in a // superclass and silently break things like autorotation. id <EventInterceptWindowDelegate> eventInterceptDelegate; } @property(nonatomic, assign) id <EventInterceptWindowDelegate> eventInterceptDelegate; @end

EventInterceptWindow.m:

#import "EventInterceptWindow.h" @implementation EventInterceptWindow @synthesize eventInterceptDelegate; - (void)sendEvent:(UIEvent *)event { if ([eventInterceptDelegate interceptEvent:event] == NO) [super sendEvent:event]; } @end

Cree esa clase, cambie la clase de su UIWindow en su MainWindow.xib a EventInterceptWindow, luego, en algún lugar, establezca eventInterceptDelegate en un controlador de vista que desee interceptar eventos. Ejemplo que intercepta un doble toque:

- (BOOL)interceptEvent:(UIEvent *)event { NSSet *touches = [event allTouches]; UITouch *oneTouch = [touches anyObject]; UIView *touchView = [oneTouch view]; // NSLog(@"tap count = %d", [oneTouch tapCount]); // check for taps on the web view which really end up being dispatched to // a scroll view if (touchView && [touchView isDescendantOfView:webView] && touches && oneTouch.phase == UITouchPhaseBegan) { if ([oneTouch tapCount] == 2) { [self toggleScreenDecorations]; return YES; } } return NO; }

Información relacionada aquí: http://iphoneincubator.com/blog/windows-views/360idev-iphone-developers-conference-presentation

Estoy buscando implementar un pellizco de entrada / salida en la parte superior de un UITableView, he visto varios métodos, incluido este:

Pregunta similar

Pero mientras puedo crear un objeto UIViewTouch y superponerlo en mi UITableView, los eventos de desplazamiento no se retransmiten a mi UITableView, todavía puedo seleccionar celdas y responden correctamente activando una transición a un nuevo objeto ViewController. Pero no puedo desplazar el UITableView a pesar de pasar los toques Empieza, toca, mueve y toca eventos terminados.


Nimrod escribió:

en algún lugar establezca eventInterceptDelegate en un controlador de vista en el que desee interceptar eventos

No entendí inmediatamente esta declaración. Para el beneficio de cualquier otra persona que tuvo el mismo problema que yo, la forma en que lo hice fue agregando el siguiente código a mi subclase UIView que debe detectar los toques.

- (void) viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; // Register to receive touch events MyApplicationAppDelegate *appDelegate = (MyApplicationAppDelegate *) [[UIApplication sharedApplication] delegate]; EventInterceptWindow *window = (EventInterceptWindow *) appDelegate.window; window.eventInterceptDelegate = self; } - (void) viewWillDisappear:(BOOL) animated { // Deregister from receiving touch events MyApplicationAppDelegate *appDelegate = (MyApplicationAppDelegate *) [[UIApplication sharedApplication] delegate]; EventInterceptWindow *window = (EventInterceptWindow *) appDelegate.window; window.eventInterceptDelegate = nil; [super viewWillDisappear:animated]; } - (BOOL) interceptEvent:(UIEvent *) event { NSLog(@"interceptEvent is being called..."); return NO; }


Esta versión de interceptEvent: es una implementación simple de detección de pellizco para acercar. NÓTESE BIEN. Parte del código fue tomado de Beginning iPhone 3 Development by Apress.

CGFloat initialDistance; - (BOOL) interceptEvent:(UIEvent *) event { NSSet *touches = [event allTouches]; // Give up if user wasn''t using two fingers if([touches count] != 2) return NO; UITouchPhase phase = ((UITouch *) [touches anyObject]).phase; CGPoint firstPoint = [[[touches allObjects] objectAtIndex:0] locationInView:self.view]; CGPoint secondPoint = [[[touches allObjects] objectAtIndex:1] locationInView:self.view]; CGFloat deltaX = secondPoint.x - firstPoint.x; CGFloat deltaY = secondPoint.y - firstPoint.y; CGFloat distance = sqrt(deltaX*deltaX + deltaY*deltaY); if(phase == UITouchPhaseBegan) { initialDistance = distance; } else if(phase == UITouchPhaseMoved) { CGFloat currentDistance = distance; if(initialDistance == 0) initialDistance = currentDistance; else if(currentDistance - initialDistance > kMinimumPinchDelta) NSLog(@"Zoom in"); else if(initialDistance - currentDistance > kMinimumPinchDelta) NSLog(@"Zoom out"); } else if(phase == UITouchPhaseEnded) { initialDistance = 0; } return YES; }


Edición: si bien este código funcionó bien al 100% en el simulador de iPhone, cuando lo ejecuté en un dispositivo iPhone encontré errores extraños relacionados con el desplazamiento de la tabla. Si esto también te sucede, entonces fuerza el método interceptEvent: para devolver NO en todos los casos. Esto significa que la superclase también procesará el evento táctil, pero afortunadamente esto no rompió mi código.