【问题标题】:Gesture Recognizers Attatched To Overlay View On Top Of ScrollView?手势识别器附加到滚动视图顶部的覆盖视图?
【发布时间】:2017-04-21 23:02:09
【问题描述】:

我有一个滚动视图,它位于覆盖整个屏幕的覆盖视图下方。在这个覆盖视图上,我有一个迷你视图。我在overlayView上附加了一个平移手势,当这个平移手势向上/向下拖动时,它会动画迷你视图的增长/收缩。我的目标是,当我到达滚动视图的底部时,如果我再次向上滑动,它会调用 overlayView 的平移手势来动画 miniView 的增长。但是,如果我从这个位置向下滑动,它会像往常一样向上滚动滚动视图。我的问题是我无法弄清楚如何将触摸保持在我的覆盖视图中,或者将它们传递给可以正常滚动的滚动视图。我需要能够以某种方式访问​​一个函数,它允许我使用 if 语句(如果 scrollView.isAtCertainPoint && swipeWasInCertainDirection),然后选择是否将移动传递给 scrollView 或 overlayView。这是我的视图层次结构:
-父视图
-----覆盖视图 ----------滚动视图
---------Mini View(overlayView的子视图)

我正在尝试重新创建应用程序 Bumble 的向上/向下滑动,如果这有帮助的话。在此先感谢,我一直在到处寻找,但似乎找不到解决方案。

【问题讨论】:

    标签: ios swift uiscrollview uigesturerecognizer uipangesturerecognizer


    【解决方案1】:

    嗯,我想出了自己问题的答案。不确定这是否是最有效/最干净的方法,但这是获得预期效果的唯一方法。这是我的解决方案:在我的叠加视图中,我覆盖了

        override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        if miniView.frame.contains(point) || miniView.isOpen {
            return true
        }
        //pass the tap onto other views
        return false
    }
    

    这基本上允许我说视图是否应该具有 userInteraction,这是我基于某些标准(点击在我的 miniView 内或 miniView 已放大)。但是,当我返回 false 时,它​​会让触摸通过。如果你没有重写这个方法并且overlayView 有userInteractionEnabled,那么overlay 视图会吃掉所有的触摸。使用这种方法,我仍然可以将 userInteractionEnabled 保留在 overlayView 上,但可以决定何时应该将触摸传递到其他地方。

    然后,在我的 parentView 中,我添加了一个平移手势。我把parentView做成了一个UIGestureRecognizerDelegate,并实现了这个功能:

    override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        //if the final page is the first page (i.e. the user only has one pic), then we don't want swiping that could interfere with the card swipe.
        if let pan = gestureRecognizer as? UIPanGestureRecognizer {
            let velocity = pan.velocity(in: self)
            let isVertical = abs(velocity.x) < abs(velocity.y)
            let isUpwards = getPanDirection(velocity: velocity) == .up
            return (theBumbleScrollView.isAtFinalPage && isVertical && isUpwards) || theBumbleDetailView.isOpen
        }
        return true
    }
    

    这让我可以看到平移手势何时开始,并且根据我返回的内容(真或假),它会将平移手势的状态更改为 .failed。基本上,取消它的手势。这是一个有用的 Stack OverFlow 帖子:Limit UIView movement to only vertical or horizontal axis

    现在,根据我指定的标准,我的平移手势失败了,但我需要告诉我的滚动视图,如果我的自定义平移手势失败,它的平移手势可以进行平移。这就是这个方便的行出现的地方 require(toFail: ...):

        let pan = UIPanGestureRecognizer(target: self, action: #selector(self.isPanning(pan:)))
        pan.delegate = self
        self.addGestureRecognizer(pan)
        theScrollView.panGestureRecognizer.require(toFail: pan)
    

    当我在父视图上设置平移手势时,我基本上告诉滚动视图的平移手势(苹果自动内置)如果自定义平移手势失败,它应该是下一个。

    这是允许我有时在我的 scrollView 上滚动但其他时候能够在我的 overlayView 上滚动的解决方案。希望我能在我弄清楚这一点的那一天拯救某人。如果有人想查看示例代码,我还为我的示例项目创建了一个 github 存储库(视图名称不同)。 https://github.com/danielchangsoojones/Bumble-App-Clone/tree/master

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-29
      相关资源
      最近更新 更多