Pregunta

Estoy buscando para poner en práctica una pizca de entrada / salida en la parte superior de un UITableView, he mirado varios métodos incluyendo éste:

pregunta similares

Pero mientras pueda crear un objeto UIViewTouch y cubrirás en mi UITableView, desplazarse eventos no están siendo transmitidas a mi UITableView, todavía puedo seleccionar celdas, y responder adecuadamente mediante la activación de una transición a un nuevo objeto ViewController. Pero no puedo desplazar la UITableView a pesar de pasar la touchesBegan, touchesMoved y touchesEnded eventos.

¿Fue útil?

Solución

Esto parece ser un problema clásico. En mi caso yo quería para interceptar algunos eventos durante un UIWebView que no puede tener subclases, etc, etc.

He encontrado que la mejor manera de hacerlo es interceptar los eventos utilizando el UIWindow:

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

Crear esa clase, cambie la clase de su UIWindow en su MainWindow.xib a EventInterceptWindow, a continuación, establezca algún lugar del eventInterceptDelegate a un controlador de vista que desea interceptar eventos. Ejemplo que intercepta una doble pulsación:

- (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;
}

Related info aquí: http://iphoneincubator.com/blog/windows-views/360idev -Iphone-developers-conferencia-presentación

Otros consejos

Nimrod escribió:

  

set alguna parte del eventInterceptDelegate a un controlador de vista que desea interceptar eventos

Yo no entendía inmediatamente esta declaración. Para el beneficio de cualquier otra persona que tenía el mismo problema que yo, la forma en que lo hice fue añadiendo el siguiente código a mi subclase UIView que debe detectar 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 sencilla de detección de pellizcar para zoom. NÓTESE BIEN. Parte del código fue tomada desde el principio del iPhone 3 Desarrollo por 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;
}


Editar: Si bien este código trabajó 100% bien en el simulador de iPhone, cuando me encontré con él en un dispositivo iPhone me encontré con errores extraños relacionados con el desplazamiento de mesa. Si esto también sucede a usted, a continuación, forzar el método para volver interceptEvent: NO en todos los casos. Esto significa que la superclase también procesará el evento táctil, pero afortunadamente esto no romper mi código.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top