ios - 在 iOS 14 中使用 "long press back button"功能时,UINavigationController View Controller 堆栈顺序不正确

标签 ios swift uinavigationcontroller uikit ios14

我注意到,在 iOS 14 中使用长按后退按钮功能时,与 UINavigationController 的 View Controller 堆栈(.viewControllers.topViewController 等)似乎不正确。具体来说,顺序是颠倒的。

关于 .viewControllers 属性,Apple 的文档状态:

The root view controller is at index 0 in the array, the back view controller is at index n-2, and the top controller is at index n-1, where n is the number of items in the array.

如果我在导航堆栈中有三个 View Controller ,如下所示 [ViewController01, ViewController02, ViewController03] 并打印出 viewWillAppear 中的 .viewControllers 属性,我得到预期的输出:

[ViewController01]
[ViewController01, ViewController02]
[ViewController01, ViewController02, ViewController03]

如果我点击 ViewController03 的后退按钮,我会从 ViewController02 中的 viewWillAppear 获得预期的输出:

[ViewController01, ViewController02]

但是,如果我重新设置所有内容,得到 [ViewController01, ViewController02, ViewController03],然后使用长按后退按钮功能跳回到 ViewController01,我得到了以下的意外输出:

[ViewController03, ViewController01]

来自 ViewController01 中的 viewWillAppear

我没想到会这样,因为 ViewController03 不是,也从来不是导航堆栈的 Root View Controller 。根据文档,我期望:

[ViewController01, ViewController03]

有人可以告诉我这是预期的行为还是我忽略了一些非常明显的事情?

谢谢!

我已经在一个基于“单 View Controller ”项目的小型示例应用程序中重现了这一点。只需将初始 View Controller 嵌入导航堆栈并包含以下内容:

class StubViewController: UIViewController {

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        print("\(self) will appear. Current nav stack follows:")
        print("\(self.navigationController?.viewControllers ?? [])")
    }

}

class ViewController: StubViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.navigationController?.pushViewController(TestViewController01(), animated: true)
    }

}

class TestViewController01: StubViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.navigationController?.pushViewController(TestViewController02(), animated: true)
    }

}

class TestViewController02: StubViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        self.navigationController?.pushViewController(TestViewController03(), animated: true)
    }
}

class TestViewController03: StubViewController {
}

(我知道上面的内容很可怕)

最佳答案

基本上,这里发生的事情是您无意中看到了香肠工厂的内部,并且看到了香肠是如何制作的。而且它不漂亮...!

解决方法是:不要那样做。在你查看它之前给 View Controller 堆栈一个安顿下来的机会:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    DispatchQueue.main.async {
        print("\(self) will appear. Current nav stack follows:")
        print("\(self.navigationController?.viewControllers ?? [])")
    }
}

更简单:只需将代码移动到 viewDidAppear

关于ios - 在 iOS 14 中使用 "long press back button"功能时,UINavigationController View Controller 堆栈顺序不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65184222/

相关文章:

ios - NavigationConroller 中的 TabBarController

ios - 在 MKMapView 上设置多个引脚,并让 Callout View 显示正确的信息?

iphone - 一段时间后关闭 ViewController?

swift - iOS 11 的默认导航样式错位

swift - 为什么我需要 swift 中的下划线?

ios6 - 导航栏设置背景图像在 ios6 中不起作用

iphone - 如何仅隐藏/禁用第一个 uinavigationbar?

ios - 为什么在我的框架中我可以访问 Storyboard_a.storyboard 而无法访问 Storyboard_b.storyboard?

ios - 上传二进制文件后提交应用内购买

swift - RxSwift Driver 值的变异