StoryBordで画面遷移を行う(Objective-c)

# StoryBordで画面遷移を行う
## 目的
- 複数回に分けて、最近Objective-cによる開発でハマったポイントと対策を整理して記載します
- 主に画面遷移・テーブル周りが中心となります
- レベルは、基礎的な内容になります
- ちょっとずつ加筆します

## 環境
- Objective-c
- 対象OS iOS

## 1 StoryBordでUIを準備する
### 1.1 画面の配置
- 初期表示されている画面パーツを除去し、NavigationControllerを設置します
![スクリーンショット 2017-04-24 0.27.07.png](https://qiita-image-store.s3.amazonaws.com/0/57455/af313856-be2f-6b0c-c1f5-e9f871c291a9.png)

- グレーの色をしたNavigationViewControllerにひもづく任意のViewController(画面)を設置
- 今回、二つの画面を遷移するため、ViewControllerを二つ設置します

### 1.2 セグエの設定
- まずはRootViewControllerを設定します
- NavigationControllerを選択しcontrollerを押しながらドラッグし最初に表示する画面のViewControllerを接続します
 ![スクリーンショット 2017-04-24 0.03.08.png](https://qiita-image-store.s3.amazonaws.com/0/57455/d5cb0e9b-ac3e-4c68-065e-9fddcf5fd512.png)
- この時、上記のようなセグエの設定が現れます。最初の画面はrootViewControllerを設定します

- これから扱う全ての画面をNavigationControllerで管理するために、InitialViewControllerをNavigationContrllerに設定します
![スクリーンショット 2017-04-24 0.04.20.png](https://qiita-image-store.s3.amazonaws.com/0/57455/9a0b5a59-a36b-1d27-7802-9479598cbcdd.png)
- 上記の状態ではダメです。ViewControllerに設置されてしまっています。
- 右ペインの ***Is Initial View Controller***　のチェックを付け替えるか、
- またはこの右向きだけの矢印はInitialViewControllerを意味していますので、これをドラッグして付け替えます
- これです
![スクリーンショット 2017-04-24 0.40.49.png](https://qiita-image-store.s3.amazonaws.com/0/57455/16a8eeb1-104f-7667-c224-edf4476fe39c.png)
 
- 次に遷移先の画面を準備します
- Initialに指定したViewControllerにButtonUIを設置します。このボタンを押したら遷移するようにするつもりです
- 遷移先のViewControllerへドラッグすると設定画面が出ます。Pushを選択します
![スクリーンショット 2017-04-24 0.03.31.png](https://qiita-image-store.s3.amazonaws.com/0/57455/03cf75cf-930e-cd13-1f7d-839a8c741785.png)

### 1.3 最終的な状態
![スクリーンショット 2017-04-24 0.26.52.png](https://qiita-image-store.s3.amazonaws.com/0/57455/60d871fa-e30a-ad12-670a-06bf97ad6838.png)

- セグエはこのような形で繋がっています
![スクリーンショット 2017-04-24 0.23.00.png](https://qiita-image-store.s3.amazonaws.com/0/57455/81fdb61a-c877-c14e-81b9-6bd7a01b1bb8.png)

## 2 ソース
- ViewControllerにひもづくソースを準備します
- 以下の構成にします
- ![スクリーンショット 2017-04-24 0.49.18.png](https://qiita-image-store.s3.amazonaws.com/0/57455/050c3fe5-7930-4977-a1a9-420ce2d30e04.png)

- ViewControllerにひもづくソースの内容は以下になります。SecondViewController側も、同じようにViewControllerをSecondViewControllerに変えていただければオーケーです。
- Androidで言うところのActivityに近い位置付けで、画面上の操作を受け取ります。
- UIViewControllerを継承し、記載されているコールバックの実装を必須とします。
- 
```objc:ViewController.h
#import <UIKit/UIKit.h>

@interface ViewController : UIViewController


@end

```

```objc:ViewController.m
#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
```

- ViewDidLoadはライフサイクルメソッドで、画面が表示される直後に表示されます
- 今後少しずつこの手のメソッドを出的次第紹介します。

----
***補足***

- 日本語でディレクトリが作られている？というように一見見えますが、これはgroupというもので、実際にこのような物理的なディレクトリ構造にはなっていません
- XCodeはフラットなファイルの持ち方をしていて、ファイルがXCode上どういう配置になるかの情報を持っています。
- ですので、裏から(finder)で物理的にファイルの出し入れを行った場合、うまくXCodeに反映されないことがあります
- ですので、XCode上でファイルの出し入れなどを行うのが良いと思います。

----

- StoryBordとソースのひもづけ
- 何気にこれを忘れてはまるというのをよくやらかしました。
![スクリーンショット 2017-04-24 0.58.06.png](https://qiita-image-store.s3.amazonaws.com/0/57455/79336ecb-d8c6-6995-5334-034e95f7099f.png)
- まずひもづけるViewControllerを選択します
- ちゃんとその要素を取れているか、海藻の違うやつを取ってしまっていないか、左側のツリーで選択すると間違いがないです

![スクリーンショット 2017-04-24 0.58.16.png](https://qiita-image-store.s3.amazonaws.com/0/57455/462390d2-892e-374a-549d-3f11c7766407.png)

- 次は右側のペインで、真ん中の四角いタブを選択して、CustomClassにひもづけるUIViewControllerクラスのサブクラス（さっき作ったクラス）を設定します
- 自動で候補がでない場合があります。その場合はXCodeを再起動するか、直接入力してください。

- この状態で実行すると、ボタンを押下すると次の画面に遷移します

## 3 unwindで設定するべきこと一覧
### 3.1 Uuwindとは
- NavigationViewにおいて、Pushにて画面遷移を行うと、NavigationBar上で画面を戻る処理を入れることができる。（popする）

### 3.2 実装
- 戻り先の画面に、メソッドを追加
- IBActionを戻り値にもつ任意の名前のメソッドを、UIStoryBordSegueクラスを引数にします
- 戻りの処理が行われると、このメソッドが呼び出されます。戻ってきたとき固有の画面の初期化処理を実装します
- 
```objc:ViewController.m
- (IBAction)unwindToBefor:(UIStoryboardSegue *)segue{
}
```

### 3.3 StoryBordの設定
- StoryBordでの設定を行います

![スクリーンショット 2017-04-25 0.12.50.png](https://qiita-image-store.s3.amazonaws.com/0/57455/c198bf72-5877-70da-7f3b-11266f9eadf3.png)


![スクリーンショット 2017-04-25 0.12.46.png](https://qiita-image-store.s3.amazonaws.com/0/57455/147d3af1-e213-a06f-9251-57cc56475678.png)
- ViewControllerのヘッダにこのようなマークが付いています
- これを選択するとツリー上ではExitと言うオブジェクトを選択したことになります
- この状態で右のペインを確認すると
![スクリーンショット 2017-04-25 0.12.54.png](https://qiita-image-store.s3.amazonaws.com/0/57455/0d4269e3-6341-9167-92f8-300a50084ece.png)
先ほど指定した戻り先のメソッドが出てきます。

- この右の丸をViewControllerに紐付けます
![スクリーンショット 2017-04-25 0.16.18.png](https://qiita-image-store.s3.amazonaws.com/0/57455/064405c1-45bf-3a8c-b061-9808928a2d14.png)
- manualを選択します

![スクリーンショット 2017-04-25 0.16.25.png](https://qiita-image-store.s3.amazonaws.com/0/57455/d0d58eca-0323-5398-31c6-5d86c762a5b1.png)

- unwindSegueと言う要素が追加されます。これが遷移の戻りの処理としてViewControllerに紐付けられました


- unwindSegueの設定

![スクリーンショット 2017-04-25 0.31.27.png](https://qiita-image-store.s3.amazonaws.com/0/57455/998b26dc-232e-7e43-9394-b27c40115eb3.png)

- unwin segueを選択し、右ペインでIDentiterを設定します
![スクリーンショット 2017-04-25 0.22.29.png](https://qiita-image-store.s3.amazonaws.com/0/57455/c6613abc-f3eb-4b4f-a487-7770c9be4b36.png)

- ここで、このunwind segueの名前「identifer」を指定し、これをキーにしてセグエを選択します
- Actionは戻り先をあらわしています。

---

*** 補足 ***

- つまり、このメソッドは戻り先を指定するときに使えます
- もし二つの画面からこの画面へ遷移していたときに、どちらかPushを行ってきた画面を選んで戻りたいときは、このメソッドを選択して戻り先を決めることができます
 
---


- 戻りのアクションを設定します
- UI
- bar buttonアイテムをNavigationBarに設置します
![スクリーンショット 2017-04-25 0.23.20.png](https://qiita-image-store.s3.amazonaws.com/0/57455/1a7510ef-4652-671c-bfd7-c89d562744ad.png)

![スクリーンショット 2017-04-25 0.23.59.png](https://qiita-image-store.s3.amazonaws.com/0/57455/53353168-3365-58d2-cac8-0c401da85ca4.png)

- これを最初にpushイベントをボタンから行った時と同じように、SecondViewControllerへContorlを押しながらドラッグし、イベントを受け取ります

![スクリーンショット 2017-04-25 0.24.25.png](https://qiita-image-store.s3.amazonaws.com/0/57455/7a32736a-480b-034c-7594-c3327fdeede4.png)


- アクション
- すると、自動的にメソッドが補完されるため、以下のunwindを実行するメソッドを、unwindセグエで設定したidentifer「RETURN」として定義します

```objc:SecondViewController.m
- (IBAction)unwindToBefor:(id)sender {
    [self performSegueWithIdentifier:@"RETURN" sender:self];
}
```
## 4 画面遷移は完了
![スクリーンショット 2017-04-25 0.34.40.png](https://qiita-image-store.s3.amazonaws.com/0/57455/a3f7a720-1aff-593e-b284-22e698847f73.png)

- Buttonを押下すると画面遷移しSecondViewControllerの画面へ行きます

![スクリーンショット 2017-04-25 0.34.47.png](https://qiita-image-store.s3.amazonaws.com/0/57455/58a9bd24-2b00-1512-21ee-abb2cb9db353.png)

- NavigationBarの左マークを押下すると、最初の画面に戻ってきます

　![スクリーンショット 2017-04-25 0.34.54.png](https://qiita-image-store.s3.amazonaws.com/0/57455/8f12a9b2-f47e-6be2-9cc0-35b204f69b9c.png)


## 4.5 パラメータの受け渡し
- これで画面移動はオーケーです。
- 次は、遷移時のイベントの受け取り方、セグエの行き先の制御
- パラメータの受け渡しかたや受け取ったもので初期化するところをやります

→ 続きは次回