UIScrollView 中的 UIScreenEdgePanGestureRecognizer

UIScreenEdgePanGestureRecognizer inside a UIScrollView

我有一个包含 3 个视图的水平滚动视图。第一个视图(最左边)是地图视图。我想要的功能是用户只能通过从最右边缘滑动来进入第二个视图,因为我想要其他手势来操纵地图。但是,在第二个和第三个视图中,他们可以通过在视图上的任何地方滑动来向左或向右移动。我搜索了如何执行此操作,但对我的具体情况没有运气。

我不确定从哪里开始,所以如果有人能为我指出正确的方向,那就太好了。

到目前为止我已经尝试过:

在第一个视图中禁用滚动并添加代码:

let edgeRecognizer = UIScreenEdgePanGestureRecognizer(target: firstView, action: "goToSecondView:")
    edgeRecognizer.edges = .Right

func goToSecondView(){
    scrollView.contentOffset = CGPoint(x: self.scrollView.contentSize.width/3, y: scrollView.contentOffset.y)
}

我们不使用 UIScreenEdgePanGestureRecognizer,而是让地图视图看不到靠近屏幕右边缘的触摸。这样触摸将传递到滚动视图的 UIPanGestureRecognizer.

这是我的设置:

(注意:图片中的视图帧符合约束条件。)

我有一个包含三个“页面”视图的滚动视图。第 1 页(“MapHolder”)包含地图视图作为子视图。第 2 页(“粉红色”)和第 3 页(“绿色”)只有标签子视图,并具有背景色以便于查看。

视图尺寸限制如下:

  • 第 2 页和第 3 页被限制为与根视图(滚动视图的父视图)具有相同的宽度和高度。这意味着他们每个人都会填满屏幕。
  • 第 1 页(“MapHolder”)被限制为与根视图具有相同的高度,但被限制为根视图的宽度减去 44。
  • 地图视图被限制为与其父视图具有相同的顶部、底部和前缘,但具有与根视图相同的宽度。

因此请注意,地图视图比其父视图(第 1 页)宽。第 1 页视图已关闭“剪辑子视图”(这是默认设置),因此位于第 1 页视图之外的地图部分仍然可见,但不会收到触摸。

视图位置限制如下:

  • 滚动视图对根视图的所有四个边都有约束。这意味着滚动视图将填满屏幕。
  • 第 1 页从其顶部、底部和前缘到滚动视图都有限制。
  • 第 2 页的前缘被限制为第 1 页的后缘加上 44。
  • 第 3 页的前缘被限制为等于第 2 页的后缘。
  • 页面 3 的后缘被限制为等于滚动视图的后缘。
  • 第 1、2 和 3 页的垂直中心被限制为相等。

从页面视图到滚动视图的约束控制滚动视图的contentSize

最后,我为滚动视图打开了“启用分页”。结果:

我已经上传了故事板 to this gist。只需将其放入一个新项目(替换现有的 Main.storyboard)并使用 MapKit link 进行试用。

非常简单,只需将此委托功能放在 UIScreenEdgePanGestureRecognizer 上并设置 UIGestureRecognizerDelegate

使用 Xcode 8 和 Swift 3 :)

您需要这 3 个委托函数。

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return false
}

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive press: UIPress) -> Bool {
    return false

}

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}