【Swift】Navigation Controllerの使い方。複数画面を階層的に移動する。(Swift 2.1、XCode 7.2)

2020年6月16日

Navigation Controllerとは

本記事では、Swiftで使える部品のNavigation Controller(以下、ナビゲーションコントローラー)について説明する。

Navigation Controller

 

ナビゲーションコントローラーとは、ページ上部にナビゲーションバーを表示し、複数画面を階層的に行ったり来たりできるようにする部品である。

これだけ聞くと「前回記事」で説明したNavigation Barと同じのように思えるが、ナビゲーションコントローラーを使えば、セグエの種類をShowで接続した画面のナビゲーションバーや戻るボタンを自動で表示してくれる利点がある。

ページの階層移動を作るならナビゲーションコントローラーを使わずにはいられないくらい便利な機能だ。

Navigation Barの例

ナビゲーションコントローラーを使ってみる

ナビゲーションバーを配置して画面遷移できるものを作ってみよう。

ナビゲーションバーをストーリーボードに配置する(下図赤矢印)。すると、矢印でつながった2つの四角が現れる。左がナビゲーションコントローラーで、右がナビゲーションバーが表示されるテーブルビューである。

ちなみに、ナビゲーションコントローラーが大きな四角のため画面と思ってしまいそうだが、これは画面ではなくコントローラーなので、部品は配置できない。

今回は単純な画面遷移を試すので、ナビゲーションコントローラーと接続するビューコントローラーを最初からあったビューコントローラーに変更しよう。

Ctrlキーを押しながらナビゲーションコントローラーをドラッグ&ドロップでビューコントローラーまで運んで吹き出しのメニューを表示させ、「root view controller」を選択する(青矢印)。

テーブルビューは使わないので、紫枠の「Route View Controller」を選択し、Deleteキーで削除する。

Navigation Controllerをストーリーボードに配置する。

 

【補足】ビューコントローラーを選択した状態で、メニューの「Editor」⇒「Embed In」⇒「Navigation Controller」の順で選択すると、ビューコントローラーに接続したナビゲーションコントローラーが作られる。実はこちらのほうが楽。

 

ストーリーボードに新しいView Controllerを配置する(下図赤矢印)。青枠のViewを選択、紫枠のアトリビュートインスペクタボタンを押して設定画面を表示し、Backgroundを黄緑色に変更する。

ストーリーボードにView Controllerに追加する

 

遷移元のビューコントローラーにボタンを配置する(下図赤矢印)。紫枠のアトリビュートインスペクタボタンを押して設定画面を表示し、Titleに「次の画面へ」を入力する。

Ctrlキーを押しながらボタンをドラッグ&ドロップで遷移先のビューコントローラーまで運んで吹き出しのメニューを表示させ、「Push」または「Show」を選択する(青矢印)。

これで遷移元と遷移先のビューコントローラーがセグエで接続され、画面遷移できるようになった。

デバイス画面にボタンを配置する

 

この段階でシミュレーターを起動すると以下のエラーが発生する。「Push Segueはナビゲーションコントローラーによって管理されたものだけが利用可能」といった内容だ。

Terminating app due to uncaught exception 'NSGenericException’, reason: 'Push segues can only be used when the source controller is managed by an instance of UINavigationController.’

 

つまり、ナビゲーションを行うには、ナビゲーションを行う画面を表示する前にナビゲーションコントローラーを初期化しなければならないということだ。

なので、下図赤枠のナビゲーションコントローラーを選択、紫枠のアトリビュートインスペクタボタンを押して設定画面を表示し、Is Initial View Controllerにチェックを入れる。これによって、アプリ起動時にナビゲーションコントローラーが初期化されるようになった。

is Initial View Controller

 

以下は実際のプレイ動画。戻るボタンを自動で表示してくれるのが何とも嬉しい。

 

途中からナビゲーションを入れる

起動直後からナビゲーションを行うのではなく、ページを進んでからナビゲーションを行いたい場合はどのようにすればいいか。

ナビゲーションを行うビューコントローラーの直前までにナビゲーションコントローラーを初期化すればいいので下図のようにすれば実現できる。といいつつも、もっとスマートな方法がありそうだ。

ストーリーボードの途中にNavigation Controllerを配置する

 

以下は実際のプレイ動画

 

途中からナビゲーションを入れない

逆に、途中からナビゲーションをしないようにするにはどうすればいいか。下図のように、ナビゲーションしない画面へのセグエをPushやShow以外にする。

途中からモーダル表示に切り替える。

 

以下は実際のプレイ動画