Closed zhw511006 closed 10 years ago
I have the same issue, it's nearly impossible to open drawer using pan gesture (MMOpenDrawerGestureModeBezelPanningCenterView) when the center view controller uses a horizontal scrollview.
I tried to use setGestureShouldRecognizeTouchBlock (with MMOpenDrawerGestureModeCustom), but the issue remains even if the block returns YES
Thanks!
have the same problem. In addition,my centerViewController is a Tableview ,so I push a SubViewController from CenterViewController. In SubViewController the gesture can open drawer also,it's error. How to disabled it, should I close MMOpenDrawerGestureModePanningCenterView before push SubViewController ,and then open MMOpenDrawerGestureModePanningCenterView after popup SubViewController ? it's feel suffer,MMDrawerController is powerful, but we need more demo to show it's usage.
The example app has a table view for the center view controller.
If you have a scroll view that allows for horizontal scrolling in the center view controller, I would recommend disabling the center pan gesture as not to confuse the user from a UX perspective.
Or you could use the bezel pan instead.
Bezel pan is not working either, that was the point of my comment
This is more of a UIGesture problem than a MMDrawerController problem.
UIGestureRecognizerDelegate provides methods for managing gesture conflicts, and UIScrollView exposes the gestures that are used so you can provide more fine grained control.
If you combine those with setGestureShouldRecognizeTouchBlock on drawerController, you should be able to manage the conflict.
It s actually not as easy as it seems and can't only be achieved with the setGestureShouldRecognizeTouchBlock
To achieve it i had to use shouldRequireFailureOfGestureRecognizer
to actually disable the scrollview gesture (was the only way)
What i do is this
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
if (gestureRecognizer != self.panGesture || self.openSide != MMDrawerSideNone) {
return NO;
}
CGPoint velocity = [self.panGesture velocityInView:self.panGesture.view];
BOOL isHorizontalGesture = fabs(velocity.y) <= fabs(velocity.x);
if(isHorizontalGesture) {
CGPoint point = [gestureRecognizer locationInView:gestureRecognizer.view];
if(([self isPointContainedWithinLeftBezelRect:point] && self.leftDrawerViewController) ||
([self isPointContainedWithinRightBezelRect:point] && self.rightDrawerViewController)){
if ([otherGestureRecognizer isKindOfClass:NSClassFromString([NSString stringWithFormat:@"UIScrollView%@", @"GestureRecognizer" ])]) {
[_disabledGestures addObject:otherGestureRecognizer];
otherGestureRecognizer.enabled = NO;
return YES;
}
}
}
return NO;
}
And don't forget to re-enable the gesture in UIGestureRecognizerStateEnded
and UIGestureRecognizerStateCancelled
@farfromrefug I like your solution. A bit hacky but I don't think there is any other way. I do have a tiny improvement however: you don't need to save the reference to otherGestureRecognizer
. Re-enabling it right after disabling does the trick since the scroll view pan recognizer sends the failure message right away.
My version of your inner if is this:
if ([otherGestureRecognizer isKindOfClass:NSClassFromString(@"UIScrollViewPanGestureRecognizer")])
{
otherGestureRecognizer.enabled = NO;
otherGestureRecognizer.enabled = YES;
return YES;
}
@Majster25 Thank you! Your solution is MUCH better and actually fixed a bug of my solution (a tap would disable the scrollview). Thanks again!
is it possible to post the entire code on how you disabled your scrollview to enter - (BOOL)gestureRecognizer:(UIGestureRecognizer )gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer )otherGestureRecognizer
No problem at all. In case you're wondering, the panGestureRecognizer
is an ivar of the MMDrawerController
class. I've just edited the setupGestureRecognizers
method and stored a reference to the gesture recognizer. If you have any more questions feel free to ask.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
if (gestureRecognizer != panGestureRecognizer || self.openSide != MMDrawerSideNone)
return NO;
const CGPoint velocity = [panGestureRecognizer velocityInView:gestureRecognizer.view];
if (fabsf(velocity.y) > fabsf(velocity.x)) //If not a horizontal gesture return
return NO;
const CGPoint point = [gestureRecognizer locationInView:gestureRecognizer.view];
if (([self isPointContainedWithinLeftBezelRect:point] && self.leftDrawerViewController) || ([self isPointContainedWithinRightBezelRect:point] && self.rightDrawerViewController))
{
if ([otherGestureRecognizer isKindOfClass:NSClassFromString(@"UIScrollViewPanGestureRecognizer")])
{
otherGestureRecognizer.enabled = NO;
otherGestureRecognizer.enabled = YES;
return YES;
}
}
return NO;
}
@Majster25 After implementing MGSwipeTableCell in my apps i can even say that the delegate method can be simplified. We "should" (must...) disable/enable the other gesture in all cases:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
if (gestureRecognizer != self.panGesture || self.openSide != MMDrawerSideNone) {
return NO;
}
CGPoint velocity = [self.panGesture velocityInView:self.panGesture.view];
BOOL isHorizontalGesture = fabs(velocity.y) <= fabs(velocity.x);
if(isHorizontalGesture) {
CGPoint point = [gestureRecognizer locationInView:gestureRecognizer.view];
if(([self isPointContainedWithinLeftBezelRect:point] && self.leftDrawerViewController) ||
([self isPointContainedWithinRightBezelRect:point] && self.rightDrawerViewController)){
otherGestureRecognizer.enabled = NO;
otherGestureRecognizer.enabled = YES;
return YES;
}
}
return NO;
}
@farfromrefug Thank you very much !!! and @Majster25
hi,i find "CGPoint velocity = [self.panGesture velocityInView:self.panGesture.view];",velocity.x & y is always 0. anybody can help me? THX
@mingming1222,Please Help Me~
sorry...i dont no. 😂
发自我的 iPhone
在 2015年7月30日,19:19,lipeiran notifications@github.com 写道:
hi,i find "CGPoint velocity = [self.panGesture velocityInView:self.panGesture.view];",velocity.x & y is always 0. anybody can help me? THX
— Reply to this email directly or view it on GitHub.
"I've just edited the setupGestureRecognizers method and stored a reference to the gesture recognizer"
Just to clear the confusion to @JanHalozan 's great answer, just assign local variable pan
to panGestureRecognizer
that you defined as a property in setupGestureRecognizers
.
You must also change isPointContainedWithRightBezelRect
isPointContainedWithinRightBezelRect
(change With to Within) to fix the error.
@farfromrefug is right. We must remove that last if condition for UIScrollViewPanGestureRecognizer, because when the transitionStyle is changed to pageCurl, this check doesn't work expectedly, since pageCurl calls UIPanGestureRecognizer .
velocity.x & y is always 0.
+1
Is this already somewhere in the implementation or in a PR? Otherwise I'll submit a new pull request.
I have a UIScrollView in CenterViewController and the scrollview has three pages. When in first page, swipe to right, I hope to open the LeftViewController, how to deal with the conflict pan gesture, Thank you very much!