4

I have written a UIScrollView subclass that I am using to scroll a series of UITableViews. See the following diagram:

enter image description here

As you can see I have several vertically scrolling UITableViews, that are being scrolled horizontally inside a parent UIScrollView. This all works fine. However the application has a number of global gestures. For example, if I swipe in a given direction with 2 fingers, I do a UIView transition to another part of the app. but if I do the gesture on top of the scroll view and/or its child table views, they naturally scroll their content. This doesn't look good and causes some layout issues.

What I would like to figure out is how to disable all scrolling, on both the UIScrollView and its child UITableViews, when a user touches anywhere with two fingers, and only with two fingers. I've tried variations of overriding touchesBegan, touchesEnded, touchesShouldCancel etc... but I can't get it quite right. Any help is much appreciated.

Here is my gesture handling code:

UISwipeGestureRecognizer *twoFingerSwipeUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleTwoFingerSwipe:)];
[twoFingerSwipeUp setNumberOfTouchesRequired:2];
[twoFingerSwipeUp setDirection:UISwipeGestureRecognizerDirectionUp];
[twoFingerSwipeUp setDelegate:self];

// 'self' is the superview of the UIScrollView, which is a UIView.
[self addGestureRecognizer:twoFingerSwipeUp];

[twoFingerSwipeUp release];

// ... repeat the above code for up, down, left, right gestures ...

- (void)handleTwoFingerSwipe:(UISwipeGestureRecognizer*)swipeGesture {

    switch ([swipeGesture direction]) {

        case UISwipeGestureRecognizerDirectionUp:            
            [self changeToView:viewAbove];
            break;

        case UISwipeGestureRecognizerDirectionDown:
            [self changeToView:viewBelow];            
            break;

        case UISwipeGestureRecognizerDirectionRight:
            [self changeToView:viewToTheRight];
            break;

        case UISwipeGestureRecognizerDirectionLeft:
            [self changeToView:viewToTheLeft];
            break;            
    }
}
nrj
  • 1,701
  • 2
  • 22
  • 37

5 Answers5

1

Try setting panGestureRecognizer.maximumNumberOfTouches = 1 on all scroll and table views (iOS 5 only).

Ole Begemann
  • 135,006
  • 31
  • 278
  • 256
  • This does not work if 1 finger is on 1 tableview and your other finger is on another tableview. – nrj Nov 28 '11 at 17:19
  • 1
    Actually this doesn't seem to work at all... I can still scroll the parent scrollView side-to-side with 2 fingers. – nrj Nov 28 '11 at 18:07
1

If you're using a swipe recogniser for the two-finger swipe, require the recognisers of the scroll view (including the table views — they're scroll view as well) to fail when the two-finger recogniser recognises its gesture.

[[scrollView panGestureRecognizer] requireGestureRecognizerToFail: twoFingerRecogniser];

Iterate the above code for every scroll view and table view.

(P.S.: "recogniser" is British English, not a spelling err.)

Hope that helps. :-)

Constantino Tsarouhas
  • 6,846
  • 6
  • 43
  • 54
  • This doesn't seem to work, scrollView and tableViews all still scroll. Also, as I said in the question, I have multiple 2-finger swipe gestures and it seems like method only allows me to set one. The panGestureRecognizer accessor is also iOS 5 only. – nrj Nov 28 '11 at 17:39
0

Just disable user interaction in the parent scroll view. You need a UIWindow subclass and override -sendEvent: method because this gets called BEFORE any gesture recognizer. There, if you detect two touches, send a notification. Let the scroll view listen to it and disable user interaction if it occurs. And if touches ended, let it re-enable user interaction.

Proud Member
  • 40,078
  • 47
  • 146
  • 231
0

Write this code: scrollView.minimumZoomScale=1.0;scrollView.maximumZoomScale=1.0; scrollView.delegate self];

And Here is scrollViewDelegate Method:-

-(UIView*)viewForZoomingInScrollView:(UIScrollView *)aScrollView{ return aScrollView;}

Nishith Shah
  • 523
  • 3
  • 16
0

One thing that you should be doing is to check that the gesture has finished before acting upon it:

if (swipeGesture.state == UIGestureRecognizerStateEnded) {
   // Do your think
}

I've known odd things to happen otherwise.

tarmes
  • 15,366
  • 10
  • 53
  • 87