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>
答案 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
作为控制器参数,在这种情况下,该参数与第一次调用时的控制器相同。