The interactivePopGestureRecognizer that is associated with the UINavigationController is responsible for detecting a swipe right gesture which triggers a popViewController() to go back to the previous view controller.

You can get notified when a swipe right gesture has been recognized:

  override func viewDidLoad() {
      super.viewDidLoad()
      navigationController?.interactivePopGestureRecognizer?.addTarget(self, 
    	 action: #selector(MyViewController.handleBackswipe))
  }
    
  @objc private func handleBackswipe() {
      navigationController?.interactivePopGestureRecognizer?.removeTarget(self, 
      	  action: #selector(MyViewController.handleBackswipe))
      // do something
  }

However there seems to be no way to cancel the pop action e.g. if there are unsaved changes and you would like to ask the user what to do about these changes.

The only way I found to do this is to disable the interactivePopGestureRecognizer of the UINavigationController and to create my own UISwipeGestureRecognizer:

class MyViewController: UIViewController {
	var swipeRight: UISwipeGestureRecognizer?	    
	override func viewDidLoad() {
		super.viewDidLoad()
	
		navigationController?.interactivePopGestureRecognizer?.isEnabled = false
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        swipeRight = UISwipeGestureRecognizer(target: self,
                                              action: #selector(handleSwipe))
        if let swipeRight = swipeRight {
            swipeRight.direction = .right
            self.view.addGestureRecognizer(swipeRight)
        }
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        NotificationCenter.default.removeObserver(self)
        
        if let swipeRight = swipeRight {
            self.view.removeGestureRecognizer(swipeRight)
        }
    }
    
    
    @objc func handleSwipe(gesture: UIGestureRecognizer) {
        if let swipeGesture = gesture as? UISwipeGestureRecognizer {
            if swipeGesture == swipeRight {
                let canGoBack = checkForUnsaveChanges()
                if canGoBack {
                    _ = self.navigationController?.popViewController(animated: true)
                }
            }
        }
    }
}