UIScrollView 中的 UIScreenEdgePanGestureRecognizer

Posted

技术标签:

【中文标题】UIScrollView 中的 UIScreenEdgePanGestureRecognizer【英文标题】:UIScreenEdgePanGestureRecognizer inside a UIScrollView 【发布时间】:2016-01-11 00:26:18 【问题描述】:

我有一个带有 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)

【问题讨论】:

这个问题有点含糊。您已经标记了swift 和objective-c,您的滚动视图是用什么语言实现的。也请告诉我们你尝试了什么以及你卡在哪里。 我不介意任何一种语言的解决方案,我可以翻译。我没有尝试过任何事情,因为我不确定将 ScreenEdgePanGestureRecognizer 放在哪里,所以我不确定从哪里开始。 你有 3 个水平或垂直视图?@EthanSchatzline 看来你需要collectionview!!! 所以基本上你什么都没有,希望有人给你代码。或者您需要有关UI ScreenEdgePanGestureRecognizer 位置的建议。无论哪种方式,请更新问题,因为目前的形式要么不清楚,要么过于宽泛。 【参考方案1】:

真的很简单,只需将这个 Delegate 函数放在你的 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

【讨论】:

【参考方案2】:

我们不使用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 链接即可试用。

【讨论】:

1 描述性如此之好。打算试一试,然后告诉你进展如何。 我目前正在尝试此操作,并且正在显示地图,右侧有 44 点空白。裁剪在 mapView 的视图上被关闭。我没有像你那样设置我的故事板,我有一个视图滚动视图控制器,然后在我的故事板中有 3 个其他视图控制器,我将它们的视图放在滚动视图中。所以我不确定如何像你说的那样做约束,我猜这就是为什么它不像你的那样出现。我将 mapView.view.frame = rootView 设置为 -44 的宽度和 mapView.MKView 的 frame.width = rootView 的宽度。 我通过转到情节提要中的 MapViewController 并将 MKView 的宽度限制为 mapView 的宽度+44 来实现它。 所以现在当我对地图进行诸如去某个纬度、经度之类的事情时,我是否需要以某种方式计算它以将地图显示到左侧额外的 44 像素,以便地图销它放大到居中吗? 不,只是像正常一样计算它在地图视图的中心。

以上是关于UIScrollView 中的 UIScreenEdgePanGestureRecognizer的主要内容,如果未能解决你的问题,请参考以下文章

检测 UIScrollView 中的滚动事件并发送到 UITableView 或其他 UIScrollView

UIScrollView 子视图中的水平 UISwipeGestureRecognizer ? (UIScrollView 只需要识别垂直滚动)

UIScrollView 中的 UITextView 都在另一个 UIScrollView 中

UIScrollView 中的 UITextView 中的键盘方向

uiscrollview 中的 uitableview(滚动问题)

UIScrollView 中的 drawRect 方法