Frage

Ich suche eine Prise implementieren in / out auf einem UITableView, ich an verschiedenen Methoden ausgesehen haben so auch hier:

ähnliche Frage

Aber während ich ein UIViewTouch Objekt erstellen und überlagern sie auf meine UITableView Scrollen Ereignisse sind nicht auf meine UITableView weitergeleitet wird, kann ich immer noch Zellen auszuwählen, und sie reagieren ordnungsgemäß durch einen Übergang zu einem neuen Viewcontroller-Objekt ausgelöst wird. Aber ich kann nicht die UITableView Blättern trotz Passieren der touchesBegan, touchesMoved und touchesEnded Ereignisse.

War es hilfreich?

Lösung

Dies scheint ein klassisches Problem zu sein. In meinem Fall wollte ich einige Ereignisse über einen UIWebView abzufangen, die nicht unterklassiert werden können, etc etc.

Ich habe festgestellt, dass der beste Weg, es zu tun ist, um die Ereignisse abzufangen, die UIWindow mit:

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

diese Klasse erstellen, ändern Sie die Klasse Ihres UIWindow in Ihrem MainWindow.xib zu EventInterceptWindow, dann setzen irgendwo die eventInterceptDelegate auf einen View-Controller, die Sie möchten Ereignisse abzufangen. Beispiel, das ein Doppeltippen ab:

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

Verwandte Informationen hier: http://iphoneincubator.com/blog/windows-views/360idev -iPhone-Entwickler-Konferenz-Präsentation

Andere Tipps

Nimrod schrieb:

  

gesetzt irgendwo die eventInterceptDelegate auf einen View-Controller, die Sie möchten Ereignisse abfangen

Ich verstand nicht sofort diese Aussage. Zum Nutzen der alle anderen, die das gleiche Problem wie ich hatte, wie ich es tat, war indem Sie den folgenden Code in meine UIView-Unterklasse, die Berührungen erkennen müssen.

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


Diese Version von interceptEvent: ist eine einfache Implementierung von Pinch-to-Zoom-Erkennung. NB. Einiger Code wurde genommen von Anfang iPhone 3 Entwicklung von 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: Während dieser Code 100% fein im iPhone-Simulator gearbeitet, wenn ich es auf einem iPhone Gerät lief begegnete ich seltsame Fehler auf dem Tisch eine Rolle im Zusammenhang stehen. Wenn dies auch Ihnen passiert, zwingen dann die interceptEvent: Methode NO in allen Fällen zurückzukehren. Das bedeutet, dass die übergeordnete Klasse wird auch das Touch-Ereignis verarbeiten, aber zum Glück ist dies nicht meinen Code brechen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top