Scrollview Gesture Recognizer Eating All Touch Events

ScrollView gesture recognizer eating all touch events

This should solve your problem.

Detect touch event on UIScrollView AND on UIView's components [which is placed inside UIScrollView]

The idea is to tell the gesture recognizer to not swallow up the touch events. To do this you need to set singleTap's cancelsTouchesInView property to NO, which is YES by default.

UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
singleTap.cancelsTouchesInView = NO;
[scrollView addGestureRecognizer:singleTap];

How to send the touch events of UIScrollView to the view behind it?

First off UIScrollViews only inherently recognize UIPanGestureRecognizers and UIPinchGestureRecognizers so you need to add a UITapGestureRecognizer to the UIScrollView so it can recognize any tapping gestures as well:

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];

// To prevent the pan gesture of the UIScrollView from swallowing up the
// touch event
tap.cancelsTouchesInView = NO;

[scrollView addGestureRecognizer:tap];

Then once you receive that tap gesture and the handleTap: action is triggered, you can use locationInView: to detect whether the tap gesture's position is in fact within the frame of one of the images below your scroll view, for example:

- (void)handleTap:(UITapGestureRecognizer *)recognizer {

// First get the tap gesture recognizers's location in the entire
// view's window
CGPoint tapPoint = [recognizer locationInView:self.view];

// Then see if it falls within one of your below images' frames
for (UIImageView* image in relevantImages) {

// If the image's coordinate system isn't already equivalent to
// self.view, convert it so it has the same coordinate system
// as the tap.
CGRect imageFrameInSuperview = [image.superview convertRect:image toView:self.view]

// If the tap in fact lies inside the image bounds,
// perform the appropriate action.
if (CGRectContainsPoint(imageFrameInSuperview, tapPoint)) {
// Perhaps call a method here to react to the image tap
[self reactToImageTap:image];
break;
}
}
}

This way, the above code is only performed if a tap gesture is recognized, your program only reacts to a tap on the scroll view if the tap location falls within an image; otherwise, you can just scroll your UIScrollView as usual.

UITapGestureRecognizer on UIScrollView

The delegate class (conforming to UIGestureRecognizerDelegate) must implement

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}

This way, the tap gesture will work.

How to have a UIScrollView scroll and have a gesture recognizer?

Make a subclass of UIScrollView. Add this method in your new subclass

- (BOOL)gestureRecognizer:(UIPanGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UISwipeGestureRecognizer *)otherGestureRecognizer 
{
return YES;
}

Make your scrollView class to your new scrollview subclass.

Detect touch event on UIScrollView AND on UIView's components [which is placed inside UIScrollView]

I don't know if this works for you or not, but I've given an answer about touch events for views inside scrollview here:

Dismissing the keyboard in a UIScrollView

The idea is to tell the scrollView not to swallow up all tap gestures within the scroll view area.

I'll paste the code here anyways, hopefully it fixes your problem:

UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard)];

// prevents the scroll view from swallowing up the touch event of child buttons
tapGesture.cancelsTouchesInView = NO;

[pageScrollView addGestureRecognizer:tapGesture];

[tapGesture release];

...

// method to hide keyboard when user taps on a scrollview
-(void)hideKeyboard
{
[myTextFieldInScrollView resignFirstResponder];
}

How to receive touch events from a CollectionView embedded inside a UiView embedded inside a UIScrollView

I found the answer here by @Jaydeep and got the explanation from @zambrey.

The idea is to tell the gesture recognizer to not swallow up the touch events. To do this you need to set singleTap's cancelsTouchesInView property to NO, which is YES by default.

You want to tell the scrollView not to eat all the touch events and you do that by adding a single tap gesture recognizer to it and setting the tap’s

singleTap.cancelsTouchesInView = false

I added the tapGesture in the file that embeds the CalenderView inside the UIView inside the ScrollView and not the file that has the collectionView.

override func viewDidLoad() {
super.viewDidLoad()

createAnchors()

// add these 4 lines
let singleTap = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
singleTap.cancelsTouchesInView = false
singleTap.numberOfTapsRequired = 1
scrollView.addGestureRecognizer(singleTap)
}

// add this target method. I didn't add any code whatsoever inside of it
func handleTap(_ recognizer: UITapGestureRecognizer) {
// I literally left this blank
}


Related Topics



Leave a reply



Submit