UIPanGestureRecognizer与scrollview冲突

cyr*_*lPA 7 uiscrollview uigesturerecognizer ios uipangesturerecognizer

我正在尝试向包含滚动视图的视图添加平移手势识别器,但我想我的优先级问题.

我的全局UIView有一个UIPanGestureRecognizer设置如下:

_bottomPanGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(bottomPanGestureDetected:)];
_bottomPanGestureRecognizer.minimumNumberOfTouches = 2;
_bottomPanGestureRecognizer.maximumNumberOfTouches = 2;
_bottomPanGestureRecognizer.delaysTouchesBegan = NO;
_bottomPanGestureRecognizer.delaysTouchesEnded = NO;
Run Code Online (Sandbox Code Playgroud)

我想要识别这个手势,从底部显示另一个视图,并进行一些向下的捏合.

问题是scrollview在我之前识别它自己的平移手势.

所以我试图推迟它,这要归功于:

[_scrollView.panGestureRecognizer requireGestureRecognizerToFail:_bottomPanGestureRecognizer];
Run Code Online (Sandbox Code Playgroud)

并且它正常工作,滚动视图事件在我的两个手指向上到识别器之后被触发,但问题是现在当我只使用一个手指在滚动视图中滚动时,滚动在一小段延迟之后工作.

我想对此次活动没有任何延误,这可能吗?欢迎任何想法!

干杯.

西里尔

Nic*_*sla 7

如果它还没有解决,我解决了我的问题.

我在UIScrollView中添加了一个UIPanGestureRecognizer来检测两个手指平移手势,默认的UIScrollView行为(滚动到某些东西)仍然有效.

所以我做的是将UIPanGestureReconizer添加到UIScrollView:

UIPanGestureRecognizer *pangestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(displayReloadIndicator:)];
pangestureRecognizer.minimumNumberOfTouches = 2;
pangestureRecognizer.delegate = self;
[self.scrollView addGestureRecognizer:pangestureRecognizer];
[pangestureRecognizer release];
Run Code Online (Sandbox Code Playgroud)

在此之后我添加了代码:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {

    return YES;
}
Run Code Online (Sandbox Code Playgroud)

在此之后,我实现了平移手势识别器动作方法.

- (void) displayReloadIndicator:(UIPanGestureRecognizer*) panGestureRecognizer {

    UIGestureRecognizerState gestureRecognizerState = gestureRecognizer.state;

    CGPoint translation = [gestureRecognizer translationInView:self.scv_bibgesamt];

    if (gestureRecognizerState == UIGestureRecognizerStateBegan) {

        // create a UIView with all the Pull Refresh Headers and add to UIScrollView
        // This is really much lines of code, but its simply creating a UIView (later you'll find a myRefreshHeaderView, which is my base view) and add UIElements e.g. UIActivityIndicatorView, a UILabel and a UIImageView on it
        // In iOS 6 you will also have the possibility to add a UIRefreshControl to your UIScrollView

    }

    else if (gestureRecognizerState == UIGestureRecognizerStateEnded
             || gestureRecognizerState == UIGestureRecognizerStateCancelled) {

        if (translation.y >= _myRefreshHeaderView.frame.size.height + 12) { // _myRefreshHeaderView is my baseview

         //so the UIScrollView has been dragged down with two fingers over a specific point and have been release now, so we can refresh the content on the UIScrollView
         [self refreshContent];

         //animatly display the refresh view as the top content of the UIScrollView
         [self.scrollView setContentOffset:CGPointMake(0, myRefreshHeaderView.frame.size.height) animated:YES];
    }

    else {

         //the UIScrollView has not been dragged over a specific point so don't do anything (just scroll back to origin)
         [self.scrollView setContentOffset:CGPointMake(0, 0) animated:YES];

         //remove the view (because it's no longer needed)
         [_myRefreshHeaderView removeFromSuperview];
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:

如果您希望集成导航控制器中的滑动功能,则应集成以下代码:

- (void) viewDidLoad {

    [super viewDidLoad];


    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {

        self.navigationController.interactivePopGestureRecognizer.enabled = YES;

        self.navigationController.interactivePopGestureRecognizer.delegate = nil;
    }

    //setup view controller
}
Run Code Online (Sandbox Code Playgroud)

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {

    if (gestureRecognizer == _panGestureRecognizer
        && [self.navigationController.viewControllers count] > 1) {

        CGPoint point = [touch locationInView:self.view.window];

        if (point.x < 20
            || point.x > self.view.window.frame.size.width - 20) {

            return NO;
        }
    }

    return YES;
} 
Run Code Online (Sandbox Code Playgroud)


sim*_*one 6

实现 panRecognizer 委托以启用同时识别 UIScrollView UIGestureRecognizer

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    if (_panRecognizer == gestureRecognizer) {
        if ([otherGestureRecognizer.view isKindOfClass:UIScrollView.class]) {
            UIScrollView *scrollView = (UIScrollView *)otherGestureRecognizer.view;
            if (scrollView.contentOffset.x == 0) {
                return YES;
            }
        }
    }

    return NO;
}
Run Code Online (Sandbox Code Playgroud)

  • 非常适合我。这是 Swift 4 中的代码:`funcgestureRecognizer(_gestureRecognizer: UIGestureRecognizer, ShouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -&gt; Bool { if let scrollView = otherGestureRecognizer.view as? UIScrollView { 返回scrollView.contentOffset.x == 0 } 返回 false }` (2认同)