4

Below code, I have done for swipe to popViewController. and that's working for ios 12 or older version but when it's run in iOS 13 it is not working. the current version of Xcode is 11.1

Also, I am using a native NavigationController and navigation bar. So I don't think its an issue because of the Navigation controller.

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
    }
}
Kiran Sarvaiya
  • 1,318
  • 1
  • 13
  • 37
  • Try this man: https://stackoverflow.com/questions/43539149/swift-3-poptoviewcontroller-not-working – Mr.Javed Multani Oct 21 '19 at 10:00
  • Please read [Under what circumstances may I add “urgent” or other similar phrases to my question, in order to obtain faster answers?](//meta.stackoverflow.com/q/326569) - the summary is that this is not an ideal way to address volunteers, and is probably counterproductive to obtaining answers. Please refrain from adding this to your questions. – halfer Oct 22 '19 at 20:03

2 Answers2

2

I have fixed this issue finally after lots of try-catch. The issue is calling deinit method and not setting proper delegate on viewDidLoad Method.

Now below is the working code.

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
    }
}
Kiran Sarvaiya
  • 1,318
  • 1
  • 13
  • 37
0

You can try to check pop view controller by using following condition which is checking for iOS 13:

 if #available(iOS 13.0, *) {
                   self.navigationController?.popToViewController(vc as! YourVC, animated: true)
                } else {
                    // Fallback on earlier versions

                }

You have to look on UINavigationController changes come-up with iOS 13:

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

Mr.Javed Multani
  • 12,549
  • 4
  • 53
  • 52