我目前正在为iOS设置标签栏应用程序。
通常,我会在更改viewControllers时使用重写方法(如 prepareforSeque )进行依赖注入,但是当UITabBarController更改其活动子ViewController时,不会调用该方法。如何正确地将依赖注入到UITabBarController子ViewControllers?
答案 0 :(得分:4)
在RootViewController的viewDidLoad
中,您可以通过childViewControllers
进行迭代,找到所需的各种子控制器,并为每个子控制器设置依赖关系。在这种情况下,依赖项将在子视图控制器的viewDidLoad中可用。选项卡栏实例化子视图控制器实例,但在需要之前不加载视图。
加载标签栏视图控制器后,您可以使用委托方法注入更新的依赖项并在viewDidAppear
中使用它,因为viewDidLoad
在标签栏中选中后将不会被调用。
答案 1 :(得分:0)
通过一些额外的研究,我得出了答案。感谢Will-m我需要的线索。这个答案的当前cavaet是由TabBarController加载的第一个视图不会被注入。
为了从UITabBarController将数据注入ViewControllers,您需要执行以下操作:
首先,您需要在加载时将RootViewController设置为自己的委托。
您不一定需要控制器类作为自己的委托 除非您需要将另一个类中所需的数据直接注入UITabBarController。
您还需要将委托类声明为符合UITabBarControllerDelegate协议。
// Declare UITabBarControllerDelegate protocol
class RootViewController: UITabBarController, UITabBarControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Set class delegate to self
self.delegate = self
}
}
你需要设置RootViewController的委托,因为 委托协议包含一个重要方法: tabBarController(_:shouldSelectViewController:)。这个方法是 在RootViewController更改其活动选项卡时调用。
" viewController" tabBarController(_:shouldSelectViewController:)的参数是TabBarController切换到的子ViewController的实例。如果您已为该ViewController分配了协议(以便编译器知道您的变量是在类中声明的),则可以将该变量注入到子级中。
所以将函数添加到RootViewController类中,如下所示:
func tabBarController(tabBarController: UITabBarController, shouldSelectViewController viewController: UIViewController) {
// Get your view controller using the correct protocol.
// Use guard to make sure the correct type of viewController has been provided.
guard let vc = viewController as? YourProtocol
else { fatalError("wrong view controller type") }
// Assign the protocol variable to whatever you want injected into the class instance.
vc.VariableInYourProtocol = InjectedVariable
}
那就是它。如果您需要支持不同协议的控制器,我可能会使用switch语句编写一些内容。那 这不是我现在需要合作的东西。
另外,作为注释,此方法适用于CoreData实践,其中只有一个managedObjectContext实例在活动ViewControllers之间传递。使用此方法而不是直接从每个ViewController的应用程序委托中检索上下文的不同实例。