タブのプリロードあれこれ

UITabBarControllerのタブをプリロードする方法でハマったので備考録。

構成

StoryboardでUITabBarControllerを設置し、各Viewの前にUINavigationControllerを挟む。
タブのうち2つは同じCustomClassを設定。タブタイトルをローカライズしている。

この構成の場合、awakeFromNibをoverrideしてタブタイトルをローカライズすると、同じCustomClassを設定しているタブタイトルは別々のタイトルにできません。
そこで、起動時にこの2つのタブをプリロードして、viewDidLoadでタブタイトルをそれぞれローカライズすることにしました。

調べるとタブのプリロードは、ViewControllerの.viewにタッチすればできると書いてあったがなぜか上手くいきません。色々試した結果以下で上手くいきました。

タブを指定してプリロード

2つ目のタブをプリロードする。

1つ目のタブのCustomClassのviewDidLoadに追加
2つ目のタブのCustomClassはTab2ViewControllerとする。

①let customViewControllers = self.tabBarController!.viewControllers //TabBarControllerのタブを取得
②let tab2 = customViewControllers![1] as! UINavigationController //2つ目のタブ[1]を取得し、UINavigationControllerにキャスト
③let tab2ViewController = tab2.topViewController as! Tab2ViewController //UINavigationControllerに紐づいたViewControllerを取得してTab2ViewControllerにキャスト
④_ = tab2ViewController.view //Tab2ViewControllerのviewにタッチ

これで起動時に2つ目のタブがプリロードされました。

ちなみに、1つ目のタブと、2つ目のタブのCustomClass(Tab2ViewController)が同じ場合、Tab2ViewControllerのメンバー変数にtab = 1みたいなのを追加して、viewDidLoadに、
if (self.tab == 1) {
self.title = 1つ目のタブ名称
} else if (self.tab == 2) {
self.title = 2つ目のタブ名称
}
を追加。
③の後にtab2ViewController.tab = 2を追加すれば、タブ名称を変えられます。

全てのタブをプリロード

全てのタブをプリロードするには、起動時に読み込まれるCustomClassのviewDidLoadあたりに、

self.tabBarController!.viewControllers?.forEach {
if let navController = $0 as? UINavigationController {
navController.topViewController?.view
} else {
$0.view.description
}
}

を追加すれば、UINavigationControllerを挟んでいてもいなくても全てのタブをプリロードできます。

ちなみに、タブのViewControllerが読み込まれた時にタブのindexを取得するには以下のようなコードを書きます。

let application = UIApplication.sharedApplication().delegate as! AppDelegate
let tabbarController = application.window?.rootViewController as! UITabBarController
let selectedIndex = tabbarController.selectedIndex

selectIndexにタブのindexが入ります。

以上です。

iOS