Observing pinch multi-touch gestures in a UITableView

后端 未结 2 2107
Happy的楠姐
Happy的楠姐 2020-11-27 02:17

I am looking to implement a pinch in/out on top of a UITableView, I have looked at several methods including this one:

Similar question

But while I can cre

2条回答
  •  刺人心
    刺人心 (楼主)
    2020-11-27 03:01

    Nimrod wrote:

    somewhere set the eventInterceptDelegate to a view controller that you want to intercept events

    I didn't immediately understand this statement. For the benefit of anyone else who had the same problem as me, the way I did it was by adding the following code to my UIView subclass which must detect touches.

    - (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 implementation of pinch-to-zoom detection. NB. Some code was taken from Beginning iPhone 3 Development by 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: While this code worked 100% fine in the iPhone simulator, when I ran it on an iPhone device I encountered strange bugs related to the table scrolling. If this also happens to you, then force the interceptEvent: method to return NO in all cases. This means that the superclass will also process the touch event, but fortunately this did not break my code.

提交回复
热议问题