iOS - 如何在 Parent Push On AnotherVC 后在 NavigationController Stack 中定位 ChildVC

iOS -How to to locate ChildVC in NavigationController Stack after Parent Pushes On AnotherVC

我有一个带有选项卡的 tabBar,其中包含一个 NavVC,该 NavVC 的根作为 ParentVC。 ParentVC 有一个 segmentedControl 管理两个 childVC,RedVC 和 BlueVC。 RedVC 和 BlueVC 都包含一个用于按下 YellowVC 的按钮。

问题是当 YellowVC 被推上时,在它的 viewDidLoad 中我检查了堆栈上的视图控制器,出现的两个控制器是 ParentVC 和 YellowVC,没有提到任何一个 RedVC (如果它推动它)或 BlueVC(如果它推动它)。

for controller in navigationController!.viewControllers {

    print(controller.description) // will only print ParentVC and YellowVC
}

我知道,因为 tabBar 有一个 navVC 作为它的选项卡,它的根是 ParentVC 那么这是推送的根,但我需要知道当 YellowVC 得到时是 RedVC 还是 BlueVC 中的哪一个触发了它推进。

我可以在 YellowVC 中使用一些 class 属性,但我想看看是否有通过 navigationController 的其他方法:

var pushedFromRedVC = false // I'd prefer not to use these if I don't have to
var pushedFromBlueVC = false

当 RedVC 或 BlueVC 中的任何一个推送到 YellowVC 时,我如何获得对它们的引用?

class MyTabBarController: UITabBarController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let parentVC = ParentVC()
        let navVC = UINavigationController(rootViewController: parentVC)
        navVC.tabBarItem = UITabBarItem(title: "Parent", image: nil), tag: 0)

        viewControllers = [navVC]
    }
}

class ParentVC: UIViewController {

    var segmentedControl: UISegmentedControl! // switching segments will show either the redVC or the blueVC
    let redVC = RedController()
    let blueVC = BlueController()

    override func viewDidLoad() {
        super.viewDidLoad()

        addChildViewController(redVC)
        view.addSubview(redVC.view)
        redVC.didMove(toParentViewController: self)

        addChildViewController(blueVC)
        view.addSubview(blueVC.view)
        blueVC.didMove(toParentViewController: self)
    }
}

class RedVC: UIViewController {

    @IBAction func pushYellowVC(sender: UIButton) {

        let yellowVC = YellowVC()
        yellowVC.pushedFromRedVC = true // I'd rather not rely on this
        navigationController?.pushViewController(yellowVC, animated: true)
    }
}

class BlueVC: UIViewController {

    @IBAction func pushYellowVC(sender: UIButton) {

        let yellowVC = YellowVC()
        yellowVC.pushedFromBlueVC = true  // I'd rather not rely on this
        navigationController?.pushViewController(yellowVC, animated: true)
    }
}

class YellowVC: UIViewController {

    var pushedFromRedVC = false // only sample, I'd rather not use these if I don't have to
    var pushedFromBlueVC = false

    override func viewDidLoad() {
        super.viewDidLoad()


        for controller in navigationController!.viewControllers {
            // even though the push is triggered from either the RedVC or BlueVC it will only print ParentVC and YellowVC
            print(controller.description)
        }
    }
}

由于 RedVCBlueVC 包含在 ParentVC 中,您不会在 UINavigationController 堆栈中找到对它们的任何引用。

使用这两个布尔值的替代方法是使用 sourceVC 属性:

class YellowVC: UIViewController {

    var sourceVC: UIViewController?

    override func viewDidLoad() {
        super.viewDidLoad()

        if self.sourceVC is BlueVC {
           print("We came from Blue")
        } else if self.sourceVC is RedVC {
           print("We came from Red")
        } else {
           print("We came from somewhere else"
        }
    }
}


class RedVC: UIViewController {

    @IBAction func pushYellowVC(sender: UIButton) {

        let yellowVC = YellowVC()
        yellowVC.sourceVC = self 
        navigationController?.pushViewController(yellowVC, animated: true)
    }
}

class BlueVC: UIViewController {

    @IBAction func pushYellowVC(sender: UIButton) {

        let yellowVC = YellowVC()
        yellowVC.sourceVC = self  
        navigationController?.pushViewController(yellowVC, animated: true)
    }
}

您可能需要考虑 YellowVC 是否需要在 Red/BlueVC 上调用某些方法,或者只需要知道 Red/Blue 源隐含的某些状态。

如果是后者,那么 RedVCBlueVC 可能应该使用委托模式让 ParentVC 知道它应该推送 YellowVC 并设置适当的状态基于委托调用源的属性。

您还可以考虑将状态放入您的模型中,然后传递给 VC,而不是 VC 本身的离散属性。