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