观察UITableView中的多点触控手势

我正在寻找实施一个UITableView顶部捏,我已经看了几种方法,包括这一个:

类似的问题

但是,虽然我可以创build一个UIViewTouch对象,并将其覆盖到我的UITableView,滚动事件不会被中继到我的UITableView,我仍然可以select单元格,并通过触发到一个新的ViewController对象的转换,他们正确地响应。 但是我不能通过touchesBegan,touchesMoved和touchesEnded事件来滚动UITableView。

这似乎是一个经典问题。 在我的情况下,我想拦截一些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 

创build该类,将MainWindow.xib中的UIWindow类更改为EventInterceptWindow,然后将eventInterceptDelegate设置为要截取事件的视图控制器。 拦截双击的示例:

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

尼姆罗德写道:

某处将eventInterceptDelegate设置为您要截取事件的视图控制器

我没有立即明白这个说法。 对于和我有同样问题的其他人来说,我所做的是通过将下面的代码添加到我的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:是捏到缩放检测的简单实现。 NB。 一些代码是从Apress开始的iPhone 3开发。

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

编辑:虽然这个代码在iPhone模拟器中100%的罚款,当我在iPhone设备上运行它,我遇到了与表滚动相关的奇怪的错误。 如果这也发生在你身上,那么强制interceptEvent:方法在所有情况下都返回NO。 这意味着超类也会处理触摸事件,但幸运的是这并没有破坏我的代码。