UINavigationController Class Reference | View Controller Programming Guide for iOS
UINavigationController は UIViewController を階層的に管理するコンテナです。複数の UIViewController はスタックで管理されます。またその各 UIViewController にナビゲートするインタフェース(UINavigationBar, UIToolBar)も管理します。
UINavigationController における重要なプロパティとメソッドは以下の通りです。
プロパティ名 | 説明 |
---|---|
viewControllers | NavigationControllerで管理されているViewControllerのスタックを取得できます。 |
navigationBar | NavigationControllerを使っているときに画面上部に表示されるバー。ViewControllerのタイトルや画面遷移に関するボタンを配置します。 |
toolbar | NavigationControllerを使っているときに画面下部に表示されるバー。表示しているViewControllerに固有の操作や、あまり重要でない操作を行うボタンなどを配置することが多いです。 |
メソッド名 | 説明 |
---|---|
init(rootViewController:) |
最初に表示するViewControllerとしてrootViewControllerを渡してUINavigationControllerを生成するイニシャライザです。 |
pushViewController(_:animated:) |
引数として渡したViewControllerへ遷移します。このViewControllerはスタックに積まれ、遷移の階層が一つ深くなります。 |
popViewController(animated:) |
一つ前の階層に戻る画面遷移を行います。またスタックの階層は一つ浅くなります。 |
プロジェクトについてはbefore/day2/1.1/InfiniteNavigationSampleをご覧ください。
無限に push する画面遷移を実装しましょう。プロジェクトテンプレートで Single View Applicationを作って以下の手順で実装を行います。
- UINavigationControllerを配置して、Initial View Controllerに指定
- 無限に表示されるViewControllerのクラス(ViewController)を作成
- このクラスをstoryboard上で定義し、ボタンを追加、ボタンタップ時のハンドラをソースコードに記述して紐づける
- ボタンタップ時に新しいViewControllerにpushするようにコードを記述する
storyboard上にUINavigationControllerを配置してください。
配置時についているRoot View Controllerは、今回使用しないので削除してください。
Initial View Controllerの指定方法は、day1 1.3.1 UIViewControllerのカスタマイズ(stroyboard)で説明しているので割愛します。
UINavigationControllerからcontrol
を押しながら、ViewControllerにドラッグをすると
このようにRoot View Controllerに指定できるポップアップが表示されるので、Root View Controllerに指定してください。
このあたりは、 1.4.1 UIViewControllerのModalViewController(storyboard)で行った内容なので割愛します。
ViewControllerのstoryboard ID はクラス名と同じで、ViewController
ボタンタップ時のハンドラは pushButtonTapped(_:)
としています。
新しいViewControllerをstoryboardから生成して、pushします。
// ViewController.swift
@IBAction func pushButtonTapped(_ sender: UIButton) {
guard let viewControlelr = storyboard?.instantiateViewController(withIdentifier: "ViewController") as? ViewController else {
return
}
navigationController?.pushViewController(viewControlelr, animated: true)
}
UIViewControllerはプロパティとして navigationController
を持っています。このプロパティが自分を管理しているUINavigationControllerになるので、このプロパティに対して pushViewController(_:animated:)
を実行します。
シミュレータを実行するとViewControllerが表示され、ボタンをタップすると次々画面遷移できれば完了です。
rootView の TopBar を NavigationBar にすると、NavigationBar が現れます。これは実際に NavigationBar を設置しているのでは無く、NavigationBar がある体でレイアウトをするという意味です。この ViewController には NavigationBar が入ってくるので、それを考慮して他のレイアウトを作ることが出来ます。
確認 : navigationController.viewControllers にスタックされていることを、ログで確認してください。
- 上記で解説した、"無限にPushできる画面遷移" を実装してください
- 1.の課題にさらに、各階層をNavigationBarに表示するようにしてください。
ヒント : UIViewControllerのプロパティ title
を使います。
回答は after/day2/1.1/InfiniteNavigationSample をごらんください。
UINavigationBar Class Reference
UINavigationItem Class Reference
UINavigationBar は UINavigationItem を管理するためのコンテナです。UINavigationItem は各 ViewController が持っていて、NavigationBar に表示させる情報を管理しています。
NavigationBar 右上方にボタンを設置してみましょう。ボタンタップで pop を実装しましょう。
VIewController.swift
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let rightButton = UIBarButtonItem(title: "pop", style: .plain, target: self, action: #selector(ViewController.rightButtonTapped(_:)))
navigationItem.rightBarButtonItem = rightButton
}
func rightButtonTapped(_ sender: UIBarButtonItem) {
navigationController?.popViewController(animated: true)
}
UIAppearance Protocol Reference
UIAppearance を用いると、特定の UIComponent のデザインを一括して変更することが出来ます。
AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// 省略
if let navigationController = window?.rootViewController as? UINavigationController {
navigationController.navigationBar.setBackgroundImage(UIImage(named: "customNavBarImage1"), for: .default)
}
UINavigationBar.appearance().backgroundColor = .red
UIBarButtonItem.appearance().tintColor = .black
// 省略
}
画像データはこちら customNavBarImage1.png
画像はAssets.xcassetsに追加することで、使用できるようになります。
画像は1x、2x、3xのものをそれぞれ設定する必要があります。
最近では、pngではなくてpdfとして出力されたベクター画像を使うことが多いです。
変更できるコンポーネントとできないコンポーネントがあるんですが、 UI_APPEARANCE_SELECTOR
というアノテーションのついたプロパティは変更できます。
詳しくは http://nshipster.com/uiappearance/ をご覧ください。
以下の画面遷移を行うアプリケーションを作ってください。
プロジェクトについてはbefore/day2/1.1/NavigationSampleをご覧ください。
- 最初に表示される画面にボタンが三つ並んでいる (ボタンタイトルはそれぞれ "Button A", "Button B", "Button C")
- それぞれのボタンをタップすると次のViewControllerにpushされる
- 遷移先の画面の中央にどのボタンがタップされて遷移されたかが表示される
上の遷移図のようにstoryboardで遷移先のViewControllerを3つ全て別々に組み上げることもできますが、遷移先のViewControllerをひとつのクラスにまとめるほうがシンプルです。
- Segueを使わずに、NextViewControllerに遷移するようにしてください。
- NextViewControllerを1つにまとめてください。
以下のプロジェクトをごらんください。
after/day2/1.1/NavigationSample