【问题标题】:Swipe to go back only works on edge of screen?滑动返回仅适用于屏幕边缘?
【发布时间】:2015-12-31 01:37:18
【问题描述】:

我的滑动返回功能有效,但仅适用于屏幕边缘。我怎样才能让它在屏幕上的任何位置工作?

【问题讨论】:

  • 请分享一些代码。还有你正在使用什么 UIGestureRecognizer?什么状态?请编码!

标签: ios swift storyboard uistoryboard ios9


【解决方案1】:

实际上,在 UINavigationController 子类上执行此操作非常容易,无需对每个推送的 UIViewController 子类进行任何干预。还尊重内置的从边缘滑动状态(因此当它被有意禁用时,新手势也被禁用):

import UIKit

class NavigationController: UINavigationController {
    override func viewDidLoad() {
        super.viewDidLoad()
        setupFullWidthBackGesture()
    }

    private lazy var fullWidthBackGestureRecognizer = UIPanGestureRecognizer()

    private func setupFullWidthBackGesture() {
        // The trick here is to wire up our full-width `fullWidthBackGestureRecognizer` to execute the same handler as
        // the system `interactivePopGestureRecognizer`. That's done by assigning the same "targets" (effectively
        // object and selector) of the system one to our gesture recognizer.
        guard
            let interactivePopGestureRecognizer = interactivePopGestureRecognizer,
            let targets = interactivePopGestureRecognizer.value(forKey: "targets")
        else {
            return
        }

        fullWidthBackGestureRecognizer.setValue(targets, forKey: "targets")
        fullWidthBackGestureRecognizer.delegate = self
        view.addGestureRecognizer(fullWidthBackGestureRecognizer)
    }
}

extension NavigationController: UIGestureRecognizerDelegate {
    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        let isSystemSwipeToBackEnabled = interactivePopGestureRecognizer?.isEnabled == true
        let isThereStackedViewControllers = viewControllers.count > 1
        return isSystemSwipeToBackEnabled && isThereStackedViewControllers
    }
}

【讨论】:

  • 嘿。您将如何避免fullWidthBackGestureRecognizer 优先于其他识别器?例如,UIContextualAction 的识别器在使用此方法时会被完全忽略。它们(tableview 的识别器)也不能直接访问/它是一个私有 API……因此,我们不能在导航控制器的 UIGestureRecognizerDelegate 方法中真正使用它们。关于做什么的任何线索?否则效果很好,谢谢!
  • 垂直滚动不适用于此解决方案。
  • 甜甜甜甜的!!!!!!真棒答案!我之前在 Github 上的某个地方有过几个实现,但是这些都有问题。我还没有用 scrollViews 测试过这个想法。
【解决方案2】:

苹果说here

interactivePopGestureRecognizer

负责弹出顶视图控制器的手势识别器 离开导航堆栈。 (只读)

@property(nonatomic, readonly) UIGestureRecognizer *interactivePopGestureRecognizer

导航控制器在其视图上安装此手势识别器 并使用它从导航中弹出最顶层的视图控制器 堆。您可以使用此属性来检索手势识别器 并将其与用户中其他手势识别器的行为联系起来 界面。将手势识别器捆绑在一起时,请确保 他们同时识别他们的手势,以确保您的 手势识别器有机会处理该事件。

所以SloppySwiper 库自定义UIPanGestureRecognizer

查看库 SloppySwiper,它通过使用 UIPanGestureRecognizer 和重新创建默认动画来实现。

SloppySwiper:- UINavigationController 委托,允许从屏幕上的任何位置开始滑动手势,例如 instagram。

这个库的使用可以在here找到。

Cocoapods:- pod "SloppySwiper"

我在 ios7 及更高版本上测试了这个库。它就像一个魅力。

【讨论】:

    【解决方案3】:

    滑动返回是推送/显示视图控制器的默认行为。它从屏幕的左边缘工作(默认情况下)。如果您想从屏幕的任何部分向后滑动,您应该将 UISwipeGestureRecognizer 添加到您的视图中:
    let swipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: "didSwipe:") self.view.addGestureRecognizer(swipeGestureRecognizer)

    【讨论】:

    • 在 didSwipe 函数中我需要添加什么?
    • self.navigationController?.popViewControllerAnimated(true)
    • 它可以工作,但我无法像从屏幕边缘那样控制幻灯片?
    • 好的,所以你想要的是 UIPanGestureRecognizer 与视图控制器之间的自定义转换。在这里,您可以通过示例找到很好的答案:stackoverflow.com/a/22244990/5402342
    猜你喜欢
    • 2013-08-04
    • 2013-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-26
    • 2016-02-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多