【问题标题】:UIPanGestureRecognizer conflict with scrollviewUIPanGestureRecognizer 与滚动视图冲突
【发布时间】:2013-01-17 01:01:02
【问题描述】:

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

我的全局 UIView 有一个这样的 UIPanGestureRecognizer 设置:

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

我想识别这个手势,以便通过某种从下到上的捏合从底部显示另一个视图。

问题是滚动视图在我之前识别出它自己的平移手势。

所以我试图推迟它,感谢:

[_scrollView.panGestureRecognizer requireGestureRecognizerToFail:_bottomPanGestureRecognizer];

它正在工作,在我的两根手指向下到向上识别器之后触发了 scrollview 事件,但现在的问题是,当我只用一根手指在滚动视图中滚动时,滚动会在一小段延迟后起作用。

我希望这次活动没有延迟,这可能吗?欢迎任何想法!

干杯。

西里尔

【问题讨论】:

  • 您是否尝试将maximumNumberOfTouches_scrollView.panGestureRecognizer 设置为1
  • 是的,但奇怪的是,这个条件似乎被忽略了。
  • 嗯,另一种选择是实现UIGestureRecognizerDelegategestureRecognizerShouldBegin: 并检查那里的触摸次数。所以如果是两次触摸,return NO
  • 无法正常工作,因为:“UIScrollView 的内置平移手势识别器必须将其滚动视图作为其委托。”。似乎不可能覆盖滚动视图手势识别器委托。还有其他想法吗?
  • 您找到解决方案了吗?我遇到了同样的问题

标签: ios uiscrollview uigesturerecognizer uipangesturerecognizer


【解决方案1】:

如果还没有解决,我为我解决了问题。

我向 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];

在此之后我添加了代码:

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

    return YES;
}

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

- (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];
    }
}

更新:

如果您可能希望从导航控制器集成向后滑动功能,您应该集成以下代码:

- (void) viewDidLoad {

    [super viewDidLoad];


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

        self.navigationController.interactivePopGestureRecognizer.enabled = YES;

        self.navigationController.interactivePopGestureRecognizer.delegate = nil;
    }

    //setup view controller
}

- (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;
} 

【讨论】:

    【解决方案2】:

    实现 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;
    }
    

    【讨论】:

    • 非常适合我。这是 Swift 4 中的代码:func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -&gt; Bool { if let scrollView = otherGestureRecognizer.view as? UIScrollView { return scrollView.contentOffset.x == 0 } return false }
    【解决方案3】:

    SWIFT 4

    如果使用滚动视图,您可以在下面使用,当滚动视图在最顶部拖动时,它只是一个 panGestureRecognizer:

    translation.y > 0 表示您正在从上到下移动,并且 locationInScrollView.y

    func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
    
        let translation = scrollView.panGestureRecognizer.translation(in: scrollView.superview)
        let locationInScrollView = scrollView.panGestureRecognizer.location(in: scrollView)
    
        if translation.y > 0 && locationInScrollView.y < 500.0 {
            print("scrollView refresh:  Y: \(locationInScrollView.y)")
            setupUI()
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多