UIPanGestureRecognizer 弹出 UIViewController

Posted

技术标签:

【中文标题】UIPanGestureRecognizer 弹出 UIViewController【英文标题】:UIPanGestureRecognizer to pop UIViewController 【发布时间】:2019-06-14 21:52:01 【问题描述】:

我想知道是否真的可以在推送的UIViewController 上使用UIPanGestureRecognizer 来实现类似的行为,例如在 Telegram Messenger 聊天视图(以及许多其他流行的应用程序)中,您可以在其中简单地从屏幕上的任意位置向右滑动以返回菜单(或任何其他最初推送我们正在查看的视图控制器的视图控制器)。 我试过这段代码:

    @objc func swipeLeft(_ sender: UIPanGestureRecognizer) 
    let point = sender.translation(in: view)
    containerView.center = CGPoint(x: point.x > 0 ? view.center.x + point.x : view.center.x, y: view.center.y)
    if sender.state != .ended  return 

    if containerView.center.x < view.frame.width / 2 
        dismissSelf()
    
    else 
        UIView.animate(withDuration: 0.2) 
            self.containerView.center = self.view.center
        
    

还有一个 UIPanGestureRecognizer,如果你 presented 你的 ViewController 但它被推送时,它会很好地工作。至少现在不是这样。

现在,您会看到一个黑色视图,这也是您在推送的 UIViewController 底部的“Debug View Hiracy”中看到的内容。

感谢任何帮助!

【问题讨论】:

【参考方案1】:

我认为您正在寻找的内容已经内置于 interactivePopGestureRecognizer

self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true

如果您想制作一些自定义或不同的动画,那么我认为您需要检查过渡。这是进行自定义转换的好文章: https://medium.com/swift2go/simple-custom-uinavigationcontroller-transitions-fdb56a217dd8

【讨论】:

但是那个只是从屏幕边缘。我已经设置好了,但还希望能够从屏幕上的任何位置开始滑动。 如果您查看文章,您可以在任何您喜欢的手势识别器上处理自定义过渡。 谢谢我用这篇文章解决了!我用 UIPanGestureRecognizer 替换了 UIScreenEdgePanGestureRecognizer。【参考方案2】:

无需处理平移手势。 您可以将您的视图嵌入到导航控制器中,它会提供这样的行为(滑动返回)。

如果你不想看到导航栏,你也可以隐藏它。

用户还可以使用背面移除最顶层的视图控制器 导航栏中的按钮或使用左边缘滑动手势。

https://developer.apple.com/documentation/uikit/uinavigationcontroller

// Hide the Navigation Bar
self.navigationController?.setNavigationBarHidden(true, animated: animated)

// Show the Navigation Bar
self.navigationController?.setNavigationBarHidden(false, animated: animated)

【讨论】:

【参考方案3】:

我刚刚创建了一个 Pod,以便在导航控制器上具有类似 Telegram/Instagram 的 Pan-to-pop 行为。

你可以看到here

它允许用户:

Pan-to-pop 通常从左边缘开始(就像每个普通的UINavigationControllerPan-to-pop 来自没有 scrollView 或其他 panGesture 干扰的中心 Pan-top-pop 在任何 scrollView 的顶部,如果它们位于 offset.x = 0 处(因此它的行为类似于 Instagram)

所有这些同时保留导航控制器的所有默认功能。

要使用 CocoaPods 安装它,只需在 Podfile 中包含 pod:

pod 'EZCustomNavigation', '1.0.0'

要使用它,只需使用EZNavigationController 而不是默认的UINavigationController,它应该可以正常工作。

【讨论】:

你用什么来实现它? / 您的自定义类所基于的核心原则是什么? @unixb0y 它主要是 UINavigationController 的子类,所以一切都只是作为基础,带有自定义动画器(看起来与默认动画器完全相同)和处理交互式转换的平移手势。最困难的部分是允许在 scrollView 顶部进行平移,并区分哪个 scrollView 嵌入在我的导航控制器中,哪些没有,让任何人都可以使用它而无需做任何工作。这是通过响应者链完成的(如果我的 NavigationController 在响应者链中,则滚动视图本身嵌入其中)。希望这会有所帮助。

以上是关于UIPanGestureRecognizer 弹出 UIViewController的主要内容,如果未能解决你的问题,请参考以下文章

UIPanGestureRecognizer 碰撞

如何在父视图中限制 UIPanGestureRecognizer

UIPanGestureRecognizer 干扰滚动

未调用 iOS 13 UIPanGestureRecognizer 选择器

Swift:获取 UIPanGestureRecognizer 的目标

当对象移动到某个帧时如何停止 UIPanGestureRecognizer