UINavigationControllerDelegate‘s didShowViewContro

2020-07-03 07:25发布

问题:

class ViewController: UIViewController, UINavigationControllerDelegate {

      override func viewDidLoad() {
         super.viewDidLoad()
         navigationController!.delegate = self
      }

      func navigationController(navigationController: UINavigationController, didShowViewController viewController: UIViewController, animated: Bool) {
         print("showViewController")
      }

      func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) {
         print("sss")
      }

      func update() {
         let vc = SecondViewController()
         navigationController!.pushViewController(vc, animated: true)
      }
}

this is the first controller of my demo , and in console:

sss
showViewController
showViewController

the "didShowViewController" was called twice. I'm not sure what's going on

-----------------some test----------------------

I add some log in these method of controller : loadView,viewDidLoad ,viewWillAppear,viewDidAppear , and the order of these log is:

loadView
viewDidLoad
viewWillAppear
will:<NaviDemo.ViewController: 0x7fe8c9533050>
<NaviDemo.ViewController: 0x7fe8c9533050>
viewDidAppear
<NaviDemo.ViewController: 0x7fe8c9533050>

回答1:

I hit the same issue in my code. I was able to work around it by waiting until viewDidAppear to set the navigation delegate instead of setting it in viewDidLoad. To translate it to your example:

override func viewDidLoad() {
   super.viewDidLoad()
}

// ...

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    navigationController!.delegate = self
}


回答2:

didShowViewController is called twice because the first time it is called when the navigation controller transitions to showing the view controller. And then it is called again by the navigation controller's own viewDidAppear when it appears on screen, using the topViewController as the controller param which in this case is the same as the controller the first time it was called.



回答3:

The UINavigationController has displayed two instances of a UIViewController

From the UINavigationControllerDelegate documentation

Called just after the navigation controller displays a view controller’s view and navigation item properties.

Instead of logging "showViewController", log the UIViewController instance to see what's going on

func navigationController(navigationController: UINavigationController, didShowViewController viewController: UIViewController, animated: Bool) {
     print(viewController)
}