Skip to content
This repository has been archived by the owner on Jun 20, 2023. It is now read-only.

2.1 UINavigationController

yuichi takeda edited this page Feb 10, 2015 · 30 revisions

UINavigationController Class Reference | View Controller Programming Guide for iOS

概要

navigationController1

View Controller Programming Guide for iOS から引用

UINavigationController は UIViewController を階層的に管理するコンテナです。複数の UIViewController はスタックで管理されます。またその各 UIViewController にナビゲートするインタフェース(UINavigationBar, UIToolBar)も管理します。

navigationController2 View Controller Programming Guide for iOS から引用

UINavigationController における重要なプロパティとメソッドは以下の通りです。

プロパティ
プロパティ名 説明
viewControllers NavigationControllerで管理されているViewControllerのスタックを取得できます。
navigationBar NavigationControllerを使っているときに画面上部に表示されるバー。ViewControllerのタイトルや画面遷移に関するボタンを配置します。
toolbar NavigationControllerを使っているときに画面下部に表示されるバー。表示しているViewControllerに固有の操作や、あまり重要でない操作を行うボタンなどを配置することが多いです。
メソッド
メソッド名 説明
- initWithRootViewController: 最初に表示するViewControllerとしてrootViewControllerを渡してUINavigationControllerを生成するイニシャライザです。
- pushViewController:animated: 引数として渡したViewControllerへ遷移します。このViewControllerはスタックに積まれ、遷移の階層が一つ深くなります。
- popViewControllerAnimated: 一つ前の階層に戻る画面遷移を行います。またスタックの階層は一つ浅くなります。

実装

プロジェクトについてはSampleProjects/2.1/MixiNavigationSample2をご覧ください。

navigationController の表示、push

無限に push する画面遷移を実装しましょう。プロジェクトテンプレートで Single View Applicationを作って以下の手順で実装を行います。

  1. 無限に表示されるViewControllerのクラス(MixiViewController)を作成
  • このクラスをstoryboard上で定義し、ボタンを追加、ボタンタップ時のハンドラをソースコードに記述して紐づける
  • ボタンタップ時に新しいMixiViewControllerにpushするようにコードを記述する
  • ViewControllerが起動した時にNavigationControllerを表示する。
1 無限に表示されるViewControllerのクラス(MixiViewController)を作成
2 このクラスをstoryboard上で定義し、ボタンを追加、ボタンタップ時のハンドラをソースコードに記述して紐づける

これは 1.3の章で行った内容なので省略します。 ViewControllerのstoryboard ID はクラス名と同じで MixiViewController、 ボタンタップ時のハンドラは pushButtonTapped: としています。

img

3 ボタンタップ時に新しいMixiViewControllerにpushするようにコードを記述する

新しいMixiViewControllerをstoryboardから生成して、pushします。

// MixiViewController.m
- (IBAction)pushButtonTapped:(id)sender
{
    MixiViewController *viewController = [self.storyboard instantiateViewControllerWithIdentifier:@"MixiViewController"];
    [self.navigationController pushViewController:viewController animated:YES];
}

UIViewControllerはプロパティとして navigationController を持っています。このプロパティが自分を管理しているUINavigationControllerになるので、このプロパティに対して - pushViewController:animated:を実行します。

4. ViewControllerが起動した時にNavigationControllerを表示する

アプリケーションが起動した時に表示されるUIViewController (Xcode6ではViewControllerというクラス名)が表示されたときに MixiViewControllerをrootにもつNavigationControllerを表示します。


// ViewController.m
- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    UIViewController *viewController = [self.storyboard instantiateViewControllerWithIdentifier:@"MixiViewController"];
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
    [self presentViewController:navigationController animated:YES completion:nil];
}

シミュレータを実行するとMixiViewControllerが表示され、ボタンをタップすると次々画面遷移できれば完了です。

img

旧バージョン

以前のバージョンの資料を参考にする場合は以下のコードを参照ください。

MixiAppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.viewController = [[MixiViewController alloc] initWithNibName:@"MixiViewController" bundle:nil];
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:_viewController];
    self.window.rootViewController = navigationController;
    [self.window makeKeyAndVisible];
    return YES;
}

MixiViewController.h

#import <UIKit/UIKit.h>

@interface MixiViewController : UIViewController

- (IBAction)pressPushButton:(id)sender;

@end

MixiViewController.m

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
    self.title = [NSString stringWithFormat:@"%d", [self.navigationController.viewControllers count]];
}

- (IBAction)pressPushButton:(id)sender
{
    [self.navigationController pushViewController:[[MixiViewController alloc] init] animated:YES];
}

MixiViewController.xib xib

rootView の TopBar を NavigationBar にすると、NavigationBar が現れます。これは実際に NavigationBar を設置しているのでは無く、NavigationBar がある体でレイアウトをするという意味です。この ViewController には NavigationBar が入ってくるので、それを考慮して他のレイアウトを作ることが出来ます。

確認 : navigationController.viewControllers にスタックされていることを、ログで確認してください。

演習

  1. 上記で解説した、"無限にPushできる画面遷移" を実装してください
  • 1.の課題にさらに、各階層をNavigationBarに表示するようにしてください。

ヒント : UIViewControllerのプロパティ titleを使います。

回答は SampleProjects/2.1/MixiNavigationSample2 をごらんください。

NavigationBar UINavigationItem

UINavigationBar Class Reference

UINavigationItem Class Reference

UINavigationBar は UINavigationItem を管理するためのコンテナです。UINavigationItem は各 ViewController が持っていて、NavigationBar に表示させる情報を管理しています。

UINavigationBar iOS View Controllerプロ グラミングガイド から引用

NavigationBar 右上方にボタンを設置してみましょう。ボタンタップで pop を実装しましょう。

MixiVIewController.m

- (void)viewDidLoad
{
    [super viewDidLoad];
    UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithTitle:@"pop"
                                                                    style:UIBarButtonItemStylePlain
                                                                   target:self
                                                                   action:@selector(pressPopButton)];
    self.navigationItem.rightBarButtonItem = rightButton;
}

- (void)pressPopButton
{
    [self.navigationController popViewControllerAnimated:YES];
}

カスタマイズ と UIAppearance protocol

UIAppearance Protocol Reference

UIAppearance を用いると、特定の UIComponent のデザインを一括して変更することが出来ます。

MixiAppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    //
    [[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"customNavBarImage1"] forBarMetrics:UIBarMetricsDefault];
    [[UIBarButtonItem appearance] setTintColor:[UIColor blackColor]];
    //
}

画像データはこちら customNavBarImage1.png

変更できるコンポーネントとできないコンポーネントがあるんですが、 UI_APPEARANCE_SELECTOR というアノテーションのついたプロパティは変更できます。

詳しくは http://nshipster.com/uiappearance/ をご覧ください。

演習2.

以下の画面遷移を行うアプリケーションを作ってください。

遷移の仕様
  • 最初に表示される画面にボタンが三つ並んでいる (ボタンタイトルはそれぞれ "Button A", "Button B", "Button C")
  • それぞれのボタンをタップすると次のViewControllerにpushされる
  • 遷移先の画面の中央にどのボタンがタップされて遷移されたかが表示される

navigation-layout navigation.gif

ヒント

上の遷移図のようにstoryboardで遷移先のViewControllerを3つ全て別々に組み上げることもできますが、遷移先のViewControllerをひとつのクラスにまとめるほうがシンプルです。その際、いくつかの作り方があります。

  • Segueを使って画面遷移を行う。データの受け渡しには- prepareForSegue:sender:を用いる
  • この際、ボタンタップ時にsegueを実行するのにstoryboardから指定する方法とボタンのハンドラを作り、そこから呼び出すなどの方法があります。
  • ViewControllerを-instantiateViewControllerWithIdentifier: で作って - pushViewController:animated: で遷移する

いくつかの遷移方法がありますが、それぞれを実装してみて、メリットデメリットを実際に体感することで スムーズな画面遷移の設計を行うことができるようになります。

回答

以下のプロジェクトをごらんください。 SampleProjects/2.1/NavigationPractice

この例では、ボタンタップ時にsegueを実行し、- prepareForSegue:sender: でデータの受け渡しを行っています。

はじめに

  1. iOSについて

  2. Xcode最初のステッフ

  3. 導入

  4. Objective C の基礎

  5. メモリ管理

  6. 1.3 UIViewController1 UIViewController のカスタマイズ(xib, autoresizing)

  7. 1.3 UIViewController1 UIViewController のカスタマイズ(storyboard)

  8. UIViewController2 - ModalViewController

  9. UIViewController2 - ModalViewController(storyboard)

  10. UIViewController3 - ライフサイクル

  11. HomeWork 1 Objective C の基本文法

  12. HomeWork 2 UIViewControllerとModalViewController

  13. HomeWork 3 UIViewController + Animation

  14. UIKit 1 - container, rotate-

  15. UINavigationController

  16. UITabController

  17. Custom Container View Controller

  18. Supporting Multiple Interface Orientations

  19. HomeWork 1 - タブバーからモーダルビューを表示する

  20. HomeWork 2 - NavigationController

  21. HomeWork 2.3 デバイスことに回転対応

  22. UIKit 2- UIView -

  23. UIView

  24. UIView のカスタマイズ

  25. UIView Animation

  26. HomeWork 1 - UIScrollView

  27. UIKit 3 - table view -

  28. UITableView について

  29. UITableViewとNavigationController

  30. custom UITableViewCell の作成

  31. UITableViewのその他のオプション、カスタマイズ

  32. HomeWork 1 - Dynamic height with a custom uitableviewcell

  33. UIKit 4 - image and text -

  34. UIImagePickerController

  35. Assets Library

  36. UITextFiled, UITextView

  37. KeyboardNotification

  38. Homework 1 - フォトの複数枚選択

  39. ネットワーク処理

  40. NSURLConnection

  41. JSONのシリアライズとデシリアライズ

  42. UIWebView

  43. ローカルキャッシュと通知

  44. NSUserDefaults, Settings Bundle

  45. NSFileManager

  46. Key Value Observing

  47. NSNotification、NSNotificationCenter を用いた通知

  48. UILocalNotification

  49. Blocks, GCD

  50. Blocks

  51. GCD

  52. 【演習】GCD,-Blocksを用いたHTTPリクエストマネージャの作成

  53. 設計とデザインパターン

  54. クラス設計 1

  55. クラス設計 2

  56. [クラス設計演習] (https://github.com/mixi-inc/iOSTraining/wiki/9.3-%E3%82%AF%E3%83%A9%E3%82%B9%E8%A8%AD%E8%A8%88%E6%BC%94%E7%BF%92)

  57. 開発ツール

  58. Instruments, デバッガ

  59. CocoaPods

  60. テスト

  61. iOS開発におけるテスト

  62. GHUnit

  63. Kiwi

  64. KIF

  65. In-App Purchase

  66. In-App Purchase

  67. 付録

  68. Tips of Xcode

  69. Auto Layout 入門

  70. Auto Layout ドリル

Edit sidebar

Clone this wiki locally