UIScrollView overrides my subview's pan gesture recognizers - ios

If I have a scrollView with a subview and the subview has a pan gesture recognizer, the scrollView's pan gesture override's the subview's pan. What I want is the opposite, I think, so that is I drag a subview it will pan within the scroll view, yet if I touch another area the scroll view will pan as normal. Is there an easy way to set that up?

Here's what works for me:
UIPanGestureRecognizer *subviewPanRecognizer = [[UIPanGestureRecognizer alloc]
initWithTarget:self action:#selector(panSubview:)];
[subview addGestureRecognizer:subviewPanRecognizer];
// play nice with subview's pan gesture
[scrollView.panGestureRecognizer
requireGestureRecognizerToFail:subviewPanRecognizer];

Set canCancelContentTouches property of UIScrollView to false if you don't want to scroll on touching subviews.
Original answer

Overwrite these two delegate below,
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}
This will allow you to recognize both gestures, the default return is NO, so we need to overwrite it and return YES.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]) {
if ([otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
return NO;
}else{
return YES;
}
}
return YES;
}
In this delegate you can do anything as you wish, as it's name the gestureRecoginzer will be required to fail by the otherGestureRecognizer, all you need to do is to judge what kind of these two gestures and return YES or NO.

Related

Gesture recognizor on UICollectionView not receiving gestures

I have a ViewController with a vertically scrolling collection view that takes up the entire view. I want to be able to get swipe and pan gestures on the entire collection view (not just on cells) but I can't get any gestures. I have tried adding the gesture recognizer to the view and the collection view but neither seem to work.
Adding the gesture recognizer to the view
self.panEdgeGesture = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePan:)];
self.panEdgeGesture.delegate = self;
[self.collectionView addGestureRecognizer:self.panEdgeGesture];
[self.panEdgeGesture setEdges:UIRectEdgeRight];
Then I added these functions:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldReceiveTouch:(UITouch *)touch{
return YES;
}
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}
- (void)handlePan:(UISwipeGestureRecognizer *)sender
{
DebugLog(#"Received pan gesture");
}
Could the collection view cells stop the gesture events from triggering? They have no gestures themselves.
Per UIScreenEdgePanGestureRecognizer's Class Reference:
After creating a screen edge pan gesture recognizer, assign an
appropriate value to the edges property before attaching the gesture
recognizer to your view. You use this property to specify from which
edges the gesture may start. This gesture recognizer ignores any
touches beyond the first touch.
So change you code to:
self.panEdgeGesture = [[UIScreenEdgePanGestureRecognizer alloc];
[self.panEdgeGesture setEdges:UIRectEdgeRight];
initWithTarget:self action:#selector(handlePan:)];
self.panEdgeGesture.delegate = self;
[self.collectionView addGestureRecognizer:self.panEdgeGesture];

Adding a UIGestureRecognizer taking priority over all other interactions

When I tap on a UIButton, a UIView MyView appear from the bottom a cover a third of the screen. I would like that when I tap somewhere outside this view, it disappears.
I thought about adding another transparent UIView right under MyView and add a tab gesture on it with the dismiss function but I'm sure there is something cleaner than this.
So I thought about adding the tap gesture MyTapGesture to dismiss MyView on self.view of the UIViewController. The problem is that outside this view, I have other UIControls and gestures that capture also any touch at the same time than MyTapGesture.
How can I make MyTapGesture the priority gesture outside MyView and ignore all other gesture, taps, etc...?
You may have to use the gesture delegate methods to handle two tapGestureRecognizer activate the one you need depending on scenario
#pragma mark - UIGestureRecognizerDelegate methods
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
return YES;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
if ([tapGestureRecognizer1 isEqual:gestureRecognizer]) {
return [tapGestureRecognizer2 isEqual:otherGestureRecognizer];
}
if ([tapGestureRecognizer2 isEqual:gestureRecognizer]) {
return [tapGestureRecognizer1 isEqual:otherGestureRecognizer];
}
return NO;
}

gesture recognizer is not working on subview

I have a UIView which has a UILabel view as a subview. Now I have added gesture for self (which is UIView). UIView recognizes the touch but subview(UILabel) doesn't.
There are similar questions in stackoverflow which tells the below property to set YES. I tried but it doesn't solve.
I have also set label.userInteractionEnabled = YES.
Try this
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if ([touch.view isKindOfClass:[UILabel class]])
{
return YES;
}
return YES;
}
You may need to set the delegate of gesture recognizer as self

Disable Gesture Recognizer for UIImageView in iPad app

I have a PageControl and each page (ViewController) has different number of imageviews (UIImageView), which are created dynamically.
Each imageview is assigned a gesture recognizer (tapped or move). Since these are inside a PageControl, I would like to enable/disable the gesture recognizer so it won't interfere with the swipe to page events.
I know that there's a removeGestureRecognizer method, but I don't want to remove and attach that each time. Is there an equivalent for just enabling and disabling?
Thanks
You can use enable or disable properties of the UIGestureRecognizer like :
swipeGestureRecognizer.enabled = NO;
or you can use the gesture recognizer method return null if you don't want touches
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldReceiveTouch:(UITouch *)touch;
If you want to disable all the gestures at the same time, you can do like
imageView.userIntractionEnabled = NO;
if you want to disable only one gesture recognizer, then
NSArray *gestures = imageView.gestureRecognizers;
for(UIGestureRecognizer *gesture in gestures)
{
if([gesture isKindOfClass: [UITapGestureRecognizer class]])
{
gesture.enabled = NO;
}
Can you disable userInteractionEnabled for that UIImageView ? You could do it in Interface Builder if you are doing it that way or you could programatically set this like so - imageView.userInteractionEnabled = NO; Hope this helps...

How to unblock pan and pinch events in a UIScrollViewDelegate?

I have a UIView which has a UIScrollView subview and is a UIScrollViewDelegate. Since I've implemented viewForZoomingInScrollView I stopped getting pan and pinch events for the UIView.
How can I get these events back?
Try adding a delegate to your gesture recognizer that implements
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
try:
[yourviewname setUserInteractionEnabled:YES];
Edit: I just re-read your question. Are you saying that you can't pan and/or pinch? Or are you saying that you aren't being notified when you pan and/or pinch?

Resources