两次调用UINavigationControllerDelegate的didShowViewController方法

时间:2015-12-25 09:05:42

标签: ios swift uinavigationcontroller

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)
      }
}

这是我演示的第一个控制器,在控制台中:

sss
showViewController
showViewController

“didShowViewController”被调用了两次。 我不确定发生了什么

-----------------一些测试----------------------

我在控制器的这些方法中添加了一些日志:loadView,viewDidLoad,viewWillAppear,viewDidAppear,这些日志的顺序是:

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

4 个答案:

答案 0 :(得分:1)

覆盖viewDidLoad(..)类的UIViewController时,应始终包含super.viewDidLoad(),否则可能会出现意外行为(例如,视图控制器在预计一次时显示两次)。

尝试将super.viewDidLoad()添加到override viewDidLoad(...)

override func viewDidLoad() {
    super.viewDidLoad()

    // delegates
    navigationController!.delegate = self
}

您的日志是否仍然显示您的视图控制器显示两次?

答案 1 :(得分:1)

我在代码中遇到了同样的问题。我可以通过等待viewDidAppear设置导航委托而不是在viewDidLoad中设置它来解决这个问题。要将其翻译成您的示例:

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

// ...

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

答案 2 :(得分:0)

UINavigationController显示了两个UIViewController

的实例

来自UINavigationControllerDelegate documentation

  

导航控制器显示视图后立即调用   控制器的视图和导航项属性。

不是记录“showViewController”,而是记录UIViewController实例以查看正在发生的事情

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

答案 3 :(得分:0)

didShowViewController之所以被调用两次是因为导航控制器转换为显示视图控制器时第一次调用它。然后,当导航控制器自己的viewDidAppear出现在屏幕上时,将其再次调用,并使用topViewController作为控制器参数,在这种情况下,该参数与第一次调用时的控制器相同。