مراقبة قرصة الإيماءات متعددة اللمس في قابل للولاية

StackOverflow https://stackoverflow.com/questions/2003201

سؤال

أبحث عن تطبيق قرصة داخل / خارج أعلى من القيميت، لقد نظرت إلى عدة طرق بما في ذلك هذا واحد:

سؤال مماثل

ولكن في حين أستطيع إنشاء UIViewTouch الاعتراض والتراكب عليه على بلدي القديم، لا يتم نقل أحداث التمرير إلى My UimitalView، لا يزال بإمكاني تحديد الخلايا، ويستجيبون بشكل صحيح عن طريق تشغيل انتقال إلى كائن ViewController جديد. لكنني لا أستطيع التمرير ayitalView على الرغم من اجتياز اللمس والأحداث اللمسية والمسح.

هل كانت مفيدة؟

المحلول

يبدو أن هذا مشكلة كلاسيكية. في حالتي، أردت اعتراض بعض الأحداث على UIWebView والتي لا يمكن تصنيفها، إلخ إلخ.

لقد وجدت أن أفضل طريقة للقيام بذلك هي اعتراض الأحداث باستخدام 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

قم بإنشاء هذه الفئة، وقم بتغيير فئة UiWindow الخاصة بك في Mainwindow.xib إلى EventInterceptWindow، ثم قم بتعيين مكان EventInterEStDelegate إلى وحدة تحكم عرض تريد اعتراض الأحداث. مثال أن اعتراض النقر المزدوج:

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

المعلومات ذات الصلة هنا:http://iphoneincubator.com/blog/windows-views/360idev-iphone-developers-conference-presentation.

نصائح أخرى

كتب نمرود:

تعيين في مكان ما EventInterceptdlegate إلى وحدة تحكم عرض تريد اعتراض الأحداث

لم أفهم هذا البيان على الفور. لصالح أي شخص آخر كان لديه نفس المشكلة مثلي، الطريقة التي قمت بها من خلال إضافة التعليمة البرمجية التالية إلى Subclass Uiview الخاص بي والتي يجب أن تكتشف اللمسات.

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


هذا الإصدار من interceptEvent: هو تطبيق بسيط للكشف عن القرصة إلى التكبير. ملحوظة تم أخذ بعض الكود من بدء تطوير iPhone 3 بواسطة Acress.

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


تحرير: في حين أن هذا الرمز يعمل بشكل جيد بنسبة 100٪ في محاكاة iPhone، عندما صادفته على جهاز iPhone واجهت أخطاء غريبة متعلقة بالتمرير الجدول. إذا حدث هذا أيضا لك، ثم فرض interceptEvent: طريقة للعودة لا في جميع الحالات. هذا يعني أن SuperClass ستعالج أيضا حدث اللمس، ولكن لحسن الحظ، لم يكسر هذا الرمز الخاص بي.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top