【Swift】Navigation Controllerの設定。ナビゲーションバーのタイトルをビューコントローラーと合わせる。(Swift 2.1、XCode 7.2)
2020年6月16日
Navigation Barのタイトルを変更する
本記事では、Navigation Item(以下、ナビゲーションアイテム)に表示されるタイトルの設定方法を説明する。
Navigation Controller(以下、ナビゲーションコントローラー)と接続し、セグエの種類がPush(またはShow)でつながっている画面の上部には、下図のようにナビゲーションアイテムが表示されるので、ダブルクリックしてタイトルを変更することができる。これが一番てっとり早い。
ViewControllerのタイトルと同じにする
ViewController(以下、ビューコントローラー)もtitleプロパティを持っているので、ビューコントローラーとナビゲーションアイテムのタイトルを別々に設定するのではなく、ビューコントローラーのtitleをナビゲーションアイテムのタイトルに設定したい。
「iOS View Controllerカタログ」に以下の記述がある。
Navigation Itemにタイトルが付いていないと、Navigation BarはView Controllerのタイトルを使用します。(iOS View Controllerカタログ)
であれば、ストーリーボードでビューコントローラーのタイトルを設定してやれば、ナビゲーションアイテムのタイトルが自動で表示されそうなので試してみよう。
以降の作業を開始する段階のXcodeプロジェクトをGitHubに置いたので、手順を試してみる人はご利用されたし。
⇒「テスト用プロジェクト」
下図真ん中のビューコントローラーを選択、紫枠のアトリビュートインスペクタボタンを押して設定画面を表示し、Titleに「昼」を入力する。続いて、右端のビューコントローラーを選択し、Titleに「夕方」を入力する。
実行すると以下の動画のようになる。あれ、タイトルが表示されないぞ。
公式リファレンスのtitleプロパティの説明に以下のように記述されている。
If the view controller has a valid navigation item or tab-bar item, assigning a value to this property updates the title text those objects.(公式リファレンス)
つまり、ビューコントローラーのtitleプロパティを更新しなければナビゲーションアイテムのタイトルに反映されないということのようだ。
そこで、ViewController.swfitを以下のコードに変更する。ビューコントローラーのtitleプロパティをtitleプロパティに再設定している。titleプロパティは参照型のため、何もせずに再設定すると更新したことにならないので、空文字を付加して再設定している。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// // ViewController.swift // import UIKit class ViewController: UIViewController { //最初からあるメソッド override func viewDidLoad() { super.viewDidLoad() //タイトルを取得して再設定する。 self.title = self.title! + "" } } |
ストーリーボードを開き、夕方のビューコントローラー(下図赤枠)を選択する。水色枠のアイデンティティインスペクタボタンを押して設定画面を表示し、Classに「ViewController」を設定する。これで、昼と夕方両方で同じビューコントローラーが使われるようになった。
以下は実際のプレイ動画。タイトルが表示されるようになった。
ナビゲーションコントローラーのサブクラスでタイトルを設定する
上記の手順でタイトルが表示されるようにはなったが、あまりスマートではない。ViewControllerを増やすたびにこの処理を入れるのも冗長だ。
そこで、ナビゲーションコントローラーのサブクラスを作り、画面遷移が行われたタイミングでナビゲーションアイテムのタイトルを更新する作りにしよう。なお、先ほど変更したViewController.swiftのコードは元に戻してから作業を進めること。
メニューから「File」⇒「New」⇒「File…」を選択する。
テンプレートを選択する画面が表示されるので、「iOSのSource」⇒「Cocoa Touch Class」を選択する。
クラス名を入力する画面が表示されるので、Classに「TestNavigationController」、Subclass ofに「UINavigationController」を入力し、Nextボタンを押す。
保存先を指定する画面が表示されるので、プロジェクトと同じ場所であることを確認し、Createボタンを押す。
TestNavigationController.swiftを以下のコードに変更する。
「画面出現後の呼び出しメソッド」が呼び出されたら、ナビゲーションバーにスタックされているナビゲーションアイテムの中の一番上のアイテムのタイトルをビューコントローラーのタイトルに変更するようにした。
なぜ一番上のアイテムなのか説明すると、ナビゲーションアイテムはナビゲーションバーの中に配列で保持されていて、push、popで出し入れされながら画面遷移時に利用されるので、一番上のアイテムが遷移先画面で使われるナビゲーションアイテムになる。
ちなみに、ナビゲーションコントローラーのnavigationItemプロパティは、そのViewControllerに設定されているナビゲーションアイテムなので、このプロパティの値を変更しても画面に表示されない。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
// // TestNavigationController.swift // import UIKit class TestNavigationController: UINavigationController, UINavigationControllerDelegate { //最初からあるメソッド override func viewDidLoad() { super.viewDidLoad() //デリゲートメソッドに自分を設定する。 self.delegate = self } //画面出現後の呼び出しメソッド func navigationController(navigationController: UINavigationController, didShowViewController viewController: UIViewController, animated: Bool) { //ナビゲーションバーにスタックされている一番上のナビゲーションアイテムを取り出してタイトルを更新する。 navigationController.navigationBar.topItem!.title = viewController.title //以下のコードはタイトルは表示されない。 //navigationController.navigationItem.title = viewController.title } } |
ストーリーボードを開き、下図赤枠のナビゲーションコントローラーを選択する。紫枠のアイデンティティインスペクタボタンを押して設定画面を表示し、Classに「TestNavigationController」を設定する。これでナビゲーションコントローラーに自作したクラスが使われるようになった。
以下は実際のプレイ動画