Domanda

Sto cercando di implementare un pizzico in / out in cima ad un UITableView, ho guardato diversi metodi, tra cui questa:

domanda simile

Ma mentre posso creare un oggetto UIViewTouch e sovrapporre sul mio UITableView, scorrere gli eventi non vengono inoltrati al mio UITableView, posso ancora selezionare le celle, e rispondere adeguatamente innescando una transizione verso un nuovo oggetto ViewController. Ma non posso scorrere l'UITableView pur superando il touchesBegan, touchesMoved, e gli eventi touchesEnded.

È stato utile?

Soluzione

Questo sembra essere un problema classico. Nel mio caso ho voluto intercettare alcuni eventi nel corso di un UIWebView che non può essere sottoclassi, ecc ecc.

Ho trovato che il modo migliore per farlo è quello di intercettare gli eventi utilizzando l'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

Create quella classe, cambiare la classe del tuo UIWindow nel vostro MainWindow.xib a EventInterceptWindow, poi da qualche parte impostare l'eventInterceptDelegate ad un controller della vista che si desidera intercettare eventi. Esempio che intercetta un doppio tocco:

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

Informazioni relative qui: http://iphoneincubator.com/blog/windows-views/360idev -iPhone-sviluppatori-conferenza-presentazione

Altri suggerimenti

Nimrod ha scritto:

  

impostare da qualche parte l'eventInterceptDelegate ad un controller della vista che si desidera intercettare eventi

Non ho capito subito questa informativa. A beneficio di chiunque altro che ha avuto lo stesso problema come me, il modo in cui ho fatto è stato aggiungendo il seguente codice alla mia UIView sottoclasse che deve rilevare tocchi.

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


Questa versione di interceptEvent: è una semplice implementazione di rilevamento pinch-to-zoom. NB. Alcuni codice è stato preso da Beginning iPhone 3 Development da 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;
}


Edit: Anche se questo codice ha funzionato al 100% bene nel simulatore iPhone, quando mi sono imbattuto su un dispositivo iPhone che ho incontrato strani bug relativi alla scorrimento tavolo. Se questo accade anche a voi, quindi forzare il metodo per restituire interceptEvent: NO in tutti i casi. Ciò significa che la superclasse anche elaborare l'evento di tocco, ma per fortuna questo non rompere il mio codice.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top