I have a view, who has a UIScrollView
as subview. The frame of the UIScrollView
is about half of the root view. And I want to add some gesture handler in the root view. Because I want to know exactly when the touch begin, move and end. And for some other reason, I don't want to override the touchesBegan/touchesMove/touchesEnd
method, so I add a UILongPressGestureRecognizer
and set the minimum duration to 0. However, after I add it, the UIScrollView
doesn't work becaues all of the touch gesture have been caught by the UILongPressGestureRecognizer
. So, I want to know are there any way to pass the gesture from the UILongPressGestureRecognizer
to the UIScrollView
?

- 459
- 1
- 5
- 18
-
Best answer http://stackoverflow.com/questions/3319591/uilongpressgesturerecognizer-gets-called-twice-when-pressing-down – Yogendra Nov 10 '14 at 05:46
-
@Student Thanks. I know exactly how to use UILongPressGestureRecognizer. But the problem is that when I use it, the scrollView in the subview can't receive touches event. – Xiangyu.Wu Nov 10 '14 at 06:17
3 Answers
You can use requireGestureRecognizerToFail
method of UIGestureRecognizer
to create dependency between gestures.
UILongPressGestureRecognizer* longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressedDetected:)];
[longPress setMinimumPressDuration:0];
// longPress is only recognised if all the gesture in _scrollView fail
for (UIGestureRecognizer* recognizer in _scrollView.gestureRecognizers ) {
[longPress requireGestureRecognizerToFail:recognizer];
}
[self.view addGestureRecognizer:longPress];

- 1,109
- 7
- 5
This happens because the scrollView is subview of the view on which you add the gesture recogniser. So the view with the gesture will steal all the touches from all its subviews. Try to have a setup where the view with the gesture and the scrollView are at the same level.
Like:
RootView
|
----------------
| |
ScrollView - GestureView
Sorry for the poor graph.
EDIT
To scroll one programmatically whilst scrolling the other with the finger you can take advantage of the scrollView inheritance of the 2 components and implement scrollViewDidScroll
.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
// if user drags tableView we programmatically scroll collectionView and vice versa
UIScrollView *toScroll = scrollView == tableView ? collectionView : tableView;
// set the toScroll content offset equal to the one being dragged.
toScroll.contentOffset = scrollView.contentOffset;
}
This will give you the effect of both scrolling at the same time.
Hope it helps.
EDIT 2
Have a look at this GitHub example
You probably need to play around with the size of the cells to avoid going too far for smaller scrollViews. But this will give you a good head start.

- 1,291
- 8
- 12
-
Thank you for your answer. But in fact, I want to know whether there is any way to pass the gesture to the scrollView. – Xiangyu.Wu Nov 10 '14 at 11:56
-
I don't understand if you want to operate the long gesture on the scrollView or you want to be able to use the scrollView as normal. – Danny S Nov 10 '14 at 14:01
-
Oh, in fact, I'm in a more complex situation in which I have to use a UIScrollView combine with UILongPressGestureRecognizer. I just simplify it in this question... – Xiangyu.Wu Nov 10 '14 at 15:09
-
-
OK, thanks. In fact, I have a table view and a collection view in the same screen... And I want the two scroll view scroll synchronously. So I add gesture recogniser to handle it manually. – Xiangyu.Wu Nov 10 '14 at 16:07
-
I think there must be an elegant way to handle the scroll correctly including the decelerating... – Xiangyu.Wu Nov 10 '14 at 16:12
-
Give us some more detail. Are they next to each other? Do you want one of them to automatically scroll whilst the user scrolls the other one with his/her finger? – Danny S Nov 10 '14 at 16:36
-
They are not next to each other... And yes, I want one of them to automatically scroll whilst the user scrolls the other one with finger... – Xiangyu.Wu Nov 10 '14 at 16:46
Add this to your delegate to allow them both to be processed
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}

- 91
- 1
- 3