Observing hard touch touches in a UITableView

I'm trying to implement I / O on top of a UITableView, I looked at several methods, including this one:

Similar question

But while I can create a UIViewTouch object and overlay it on my UITableView, scroll events will not be passed to my UITableView, I can still select the cells and they will respond correctly, initiating a transition to the new ViewController object. But I can not scroll through the UITableView, despite the fact that I passed the touches of Began, touchsMoved and concerns the events Ended.

+18
iphone uitableview multi-touch
Jan 04 '10 at 23:53
source share
2 answers

This seems like a classic problem. In my case, I wanted to intercept some events on a UIWebView that cannot be subclassed, etc. Etc.

I found that the best way to do this is to intercept events using 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 this class, change the class of your UIWindow in MainWindow.xib to EventInterceptWindow, then set eventInterceptDelegate somewhere on the view controller that you want to capture events. An example that intercepts a double click:

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

Further information here: http://iphoneincubator.com/blog/windows-views/360idev-iphone-developers-conference-presentation

+41
Jan 05 '10 at 2:25
source share
— -

Nimrod wrote:

set eventInterceptDelegate somewhere on the view controller that you want to capture events

I did not immediately understand this statement. In the interest of someone who had the same problem as myself, the way I did this was to add the following code to my UIView subclass that should detect strokes.

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


This version of interceptEvent: is a simple fixed magnification discovery implementation. NB. Some code has been taken from the beginning of the development of the iPhone 3 from 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: although this code worked 100% on the iPhone simulator, when I ran it on the iPhone, I came across strange errors related to scrolling the table. If this also happens to you, then force the interceptEvent: method to return NO in all cases. This means that the superclass will also handle the touch event, but, fortunately, this did not break my code.

+5
Feb 17 2018-11-17T00:
source share



All Articles