TabBarController:依赖注入不会注入 subViewController

问题描述

我阅读了教程 denpendency injection。并尝试将它应用到我的应用程序中,在我的例子中将状态传递到 tabBarController 的每个子视图控制器。但是modelController在tabBarController的subVC中返回nil,我认为modelController实例的传递有问题,但我每几个小时都找不到它......

嗯,非常感谢任何帮助/提示

首先,我在 SceneDelegate 中创建了一个 ModelController 实例,因为它是 rootViewController。

    func scene(_ scene: UIScene,willConnectTo session: UIScenesession,options connectionoptions: UIScene.Connectionoptions) {
        guard let _ = (scene as? UIWindowScene) else { return }
        
        guard let rootViewController = window?.rootViewController as? TabBarController else {
            fatalError("Unexpected Root View Controller")
        }

        rootViewController.modelController = ModelController()
    }

然后为了测试目的,我将其注入到 tabBarController(SongsViewController) 的子视图之一中。

class TabBarController: UITabBarController {
    var modelController: ModelController!

    override func viewDidLoad() {
        super.viewDidLoad()

        guard let viewControllers = viewControllers else {
            return
        }
        
        for viewController in viewControllers {
            switch viewController {
            case let viewController as SongsViewController:
                viewController.modelController = modelController
            default:
                break
            }
        }
    }
}

最后,在 SongsViewController 中,我测试了 modelController 中的 viewWillAppear,但它返回 nil。

class SongsViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
    @IBOutlet var table: UITableView!
    
    // data source
    var songs = [Song]()
    
    // dependency injection from model controller
    var modelController: ModelController!

    override func viewDidLoad() {
        super.viewDidLoad()
        
        table.delegate = self
        table.dataSource = self
        table.rowHeight = 66
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)
        guard modelController != nil else {
            fatalError("modelController is nil")
        }
        
        loadData()
    }

解决方法

添加解决方案代码,以防以后有人遇到此问题,这样可以节省您的宝贵时间。

基本上说我们得到的第1层是navigationControllers,那么我们应该更深入地找到navigationController中的子视图。就我而言,navigationController 的第一个孩子是我想要访问的 VC naviController.viewControllers[0]

TabBarController -> NavigationControllers -> subViewControllers

因此请根据您的情况更改代码。

class TabBarController: UITabBarController {
    var modelController: ModelController!

    override func viewDidLoad() {
        super.viewDidLoad()

        guard let viewControllers = viewControllers else {
            return
        }
        
        if let naviController = viewControllers[1] as? UINavigationController {
            if let vc = naviController.viewControllers[0] as? SongsViewController {
                vc.modelController = modelController
            }
        }
       
    }
}