I have a Storyboard-based iOS Swift app that has a UITabBarController
as the main view controller which in turn has four tabs. When initializing, I want to pre-load all of them in order to have them register in my global data, like this:
Main view controller:
class MainViewController : UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
for viewController in self.viewControllers!
{
let v = viewController.view;
print("ViewController: \(v)")
}
}
Accessing the .view
should trigger viewDidLoad()
but this does not work here apparently.
Sub view controller:
class Sub1ViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
Global.sub1vc = self // register in global data
}
}
The reason is that the sub controllers' tabs should show badges with information even if the tab was not yet selected by the user.
When the program is started, all four sub VCs are listed in the print output, but only for no. 2 the viewDidLoad()
method is called (although it is actually not a direct child of the UITabBarController
but there is a SplitViewController
in between). After that, sub VC no. 1's viedDidLoad()
is called as it is actually shown in the display. Only when no. 3 or 4 are actually selected by the user, their viewDidLoad()
is called.
How can I accomplish this the "right" way? Do I have to implement init
methods for all sub controllers?
Addition:
I seem to have kind of a fix for this now: In the main view controller's viewDidLoad()
I now do this:
override func viewDidLoad() {
super.viewDidLoad()
for viewController in self.viewControllers!
{
if viewController.title == "No. 2" {
if let navctr = viewController as? UINavigationController,
ctr = navctr.viewControllers[0] as? Sub2ViewController {
G.sub2vc = ctr
}
}
}
}
This works, but it relies on having (1st) a unique title that is given to the topmost sub controller (a UINavigationController
in this case, but other types can apply as well for other tabs) and (2nd) actually knowing, i.e. coding, what way to use to access the actual sub controller from there (walking through the navigation controller in this case). I must admit having the respective target controller registering itself seems more elegant and less error-prone to me as there are no extra dependencies.