滑动到popViewController在iOS 13中不起作用

时间:2019-10-21 06:48:43

标签: ios swift uinavigationcontroller ios13 xcode11

在下面的代码中,我已经完成了向popViewController滑动的操作。并且适用于ios 12或更早版本,但是在iOS 13中运行时却无法正常工作。当前的Xcode版本是11.1

此外,我正在使用本机的NavigationController和导航栏。因此,由于导航控制器,我认为这不是问题。

import UIKit

class SwipeNavigationController: UINavigationController {

    // MARK: - Lifecycle

    override init(rootViewController: UIViewController) {
        super.init(rootViewController: rootViewController)
    }

    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)

        self.setup()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        self.setup()
    }

    private func setup() {
        delegate = self
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // This needs to be in here, not in init
        interactivePopGestureRecognizer?.delegate = self
    }

    deinit {
        delegate = nil
        interactivePopGestureRecognizer?.delegate = nil
    }

    // MARK: - Overrides

    override func pushViewController(_ viewController: UIViewController, animated: Bool) {
        duringPushAnimation = true

        super.pushViewController(viewController, animated: animated)
    }

    // MARK: - Private Properties

    fileprivate var duringPushAnimation = false
}

// MARK: - UINavigationControllerDelegate

extension SwipeNavigationController: UINavigationControllerDelegate {

    func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
        guard let swipeNavigationController = navigationController as? SwipeNavigationController else { return }

        swipeNavigationController.duringPushAnimation = false
    }

}

// MARK: - UIGestureRecognizerDelegate

extension SwipeNavigationController: UIGestureRecognizerDelegate {

    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        guard gestureRecognizer == interactivePopGestureRecognizer else {
            return true // default value
        }
        // Disable pop gesture in two situations:
        // 1) when the pop animation is in progress
        // 2) when user swipes quickly a couple of times and animations don't have time to be performed
      if (self.visibleViewController?.isKind(of: CheckOTPViewController.self))! {
        return false
      }
      if (self.visibleViewController?.isKind(of: ForgotPasswordViewController.self))! {
        return false
      }

        return viewControllers.count > 1 && duringPushAnimation == false
    }
}

2 个答案:

答案 0 :(得分:1)

经过多次尝试,我终于解决了这个问题。 问题是调用deinit方法,而不是在viewDidLoad方法上设置适当的委托。

下面是工作代码。

import UIKit

class SwipeNavigationController: UINavigationController {

    // MARK: - Lifecycle

    override init(rootViewController: UIViewController) {
        super.init(rootViewController: rootViewController)
    }

    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)

        self.setup()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        self.setup()
    }

    private func setup() {
        delegate = self
        interactivePopGestureRecognizer?.delegate = self
        navigationItem.backBarButtonItem?.isEnabled = true
        interactivePopGestureRecognizer?.isEnabled = true
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // This needs to be in here, not in init
        setup()
    }

    // MARK: - Overrides

    override func pushViewController(_ viewController: UIViewController, animated: Bool) {
        duringPushAnimation = true

        super.pushViewController(viewController, animated: animated)
    }

    // MARK: - Private Properties

    fileprivate var duringPushAnimation = false
}

// MARK: - UINavigationControllerDelegate

extension SwipeNavigationController: UINavigationControllerDelegate {

    func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
        guard let swipeNavigationController = navigationController as? SwipeNavigationController else { return }

        swipeNavigationController.duringPushAnimation = false
    }

}

// MARK: - UIGestureRecognizerDelegate

extension SwipeNavigationController: UIGestureRecognizerDelegate {

    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        guard gestureRecognizer == interactivePopGestureRecognizer else {
            return true // default value
        }
        // Disable pop gesture in two situations:
        // 1) when the pop animation is in progress
        // 2) when user swipes quickly a couple of times and animations don't have time to be performed
      if (self.visibleViewController?.isKind(of: CheckOTPViewController.self))! {
        return false
      }
      if (self.visibleViewController?.isKind(of: ForgotPasswordViewController.self))! {
        return false
      }

        return viewControllers.count > 1 && duringPushAnimation == false
    }
}

答案 1 :(得分:0)

您可以尝试通过检查iOS 13的以下条件来检查弹出视图控制器:

operator new

您必须查看iOS 13附带的UINavigationController更改:

https://medium.com/@hacknicity/view-controller-presentation-changes-in-ios-13-ac8c901ebc4e