Segueの設定（進むと戻る）

iOS9になってSegueの設定はかなり簡単になった模様。
- 結構読まれているようですので、Storyboardのキャプチャ画像を追加しました。
- unwind:forSegue: towardsViewControllerを作成sるのは「戻り先のViewController」であることに注意

##設定する遷移例
ViewAとViewBの２つのViewがある場合を例として説明します。
ViewAには「進む」ボタン、ViewBには「戻る」ボタンがあり、ViewAで「進む」ボタンを押すとViewBが現れ、ViewBで作業がおわると「戻る」ボタンでViewBの作業結果をViewAに反映してから、ViewBを消去するとします。

　ViewAで(進むボタン)-->ViewBを表示
　ViewAを表示<---------ViewBで(戻るボタン）

## 手順
###準備(ViewControler A,Bの作成）
####プロジェクトを作成
<img src="https://qiita-image-store.s3.amazonaws.com/0/115334/c8cf1800-2c4e-67c2-08e7-ad1b1de59e64.png"  width=40% ><img src="https://qiita-image-store.s3.amazonaws.com/0/115334/5c562ff1-e70c-048b-e98c-833f1f98b55e.png"  width=40% >


####コントローラ名をViewControler_Aに変更
<img src="https://qiita-image-store.s3.amazonaws.com/0/115334/12b9747a-210d-1893-3ccf-38a6db8afd41.png"  width=80% >
<img src="https://qiita-image-store.s3.amazonaws.com/0/115334/5b894c21-ddd2-41fc-03dd-8426515f3f93.png"  width=80% >

####コントローラViewControler_Bクラスを作成
<img src="https://qiita-image-store.s3.amazonaws.com/0/115334/4b6be10f-4080-a91a-1361-ba7a9a1fca6d.png"  width=80% >!<img src="https://qiita-image-store.s3.amazonaws.com/0/115334/ea6b1940-4a11-1a66-3559-77d3d6b549b5.png"  width=40% ><img src="https://qiita-image-store.s3.amazonaws.com/0/115334/df964b96-9b74-e8a1-a670-48aa9524d1d0.png"  width=40% >

####StoryboardにViewControllerを追加
<img src="https://qiita-image-store.s3.amazonaws.com/0/115334/ffc7d8bf-2442-0618-f5f9-fe7fbce56626.png"  width=80% >
####追加したViewControllerにViewControler_Bクラスをひもづけ
<img src="https://qiita-image-store.s3.amazonaws.com/0/115334/e1044e99-9121-6dbd-733a-b97794a0fb9b.png"  width=80% >

###画面遷移（進む）の設定手順
F1.StoryboardのViewAに「進むボタン」を設置
F2.Segueの作成
　　「進む」ボタンをCtrl+クリックして、遷移先のView（この例ではViewB)の上までドラッグし離す。すると、メニューが現れるのでSegueのActionを選択する。
<img src="https://qiita-image-store.s3.amazonaws.com/0/115334/a9b71063-fd3c-b48a-757b-375cb567d201.png" width=40% ><img src="https://qiita-image-store.s3.amazonaws.com/0/115334/c090097e-8b86-7a0c-b7f8-87d4282a874b.png" width=40%>
F3.(option)矢印に名前(segue identifier)をつける。
　viewAからViewBに画面遷移するときに、パラメータを渡したり、画面設定を行おうとするのであれば、ここで、このSegueに名前をつけておく。
<img src="https://qiita-image-store.s3.amazonaws.com/0/115334/d71684d7-00bd-5818-e28d-4ec96935df54.png" width=80%>
そして、ViewAの準備処理(prepareForSegue)にて、行き先を判別するために、segueのidを使用する。
具体的なコードは、下記の戻る処理でのViewBのprepareForSegueを参考に。

###画面遷移（戻る）の設定手順
B1.StoryboardのViewBに「戻るボタン」を設置
~~B2.ViewAに対応するViewControllerに~~
B2.ViewA(戻り先)に対応するViewControllerに
unwindForSegue:towardsViewController:を定義する。(名前は変えること)

```:objective-C
//ViewAのコントローラ
-(IBAction)myUnwindAction:(UIStoryboardSegue *)unwindSegue towardsViewController:(UIViewController *)subsequentVC{
}//あればよい
```

```:swift
//ViewAのコントローラ
//  2020.11.02 bug fix
//          vvvvvvvv 不要
//@IBAction override func myUnwindAction
@IBAction func myUnwindAction(for unwindSegue: UIStoryboardSegue, towardsViewController subsequentVC: UIViewController) {
}
```

B3.ViewBの戻るボタンをCtrl+ドラッグして矢印を出し、ViewBのExitで離す。すると、先ほど定義した`unwindForSegue:towardsViewController:`が現れるので、これを選択する。
<img src="https://qiita-image-store.s3.amazonaws.com/0/115334/20dc1e4b-15f7-9b5b-55df-e81633997c54.png" width=40%><img src="https://qiita-image-store.s3.amazonaws.com/0/115334/e8ec300e-f0a4-43f7-a7fe-ec5bf2da4ee3.png" width=40%>
B4.(opt)矢印に名前(segue identifier)をつける
storyboardのシーンからunwind segueを選択し、attribute inspectorを選ぶと、Storyborad Unwind SegueにIdentifierの項があらわるので、ここにsegueのidentifierをセットする。例)myRewindSegue
viewBからの画面遷移準備処理(prepareForSegue)にて、行き先を判別するためにsegueのidを利用する(サンプルプログラム参照)。
<img src="https://qiita-image-store.s3.amazonaws.com/0/115334/7ed796ab-caac-dcaf-a1a6-51be4720cdb4.png" width=80%>
B5.(opt)prepareForSegue:senderでViewAを設定する。

##処理例(Objective-C)
例えば、ViewAがアプリケーションのViewで、アプリケーションの設定編集を行うViewBで行い、編集完了後ViewAに編集を反映させることを想定する。

viewBで戻るボタンがおされると、viewBのprepareForSegueが呼ばれる。引数のsegueのidentifilerをB4で設定したsegue identifierと一致するか調べ、一致すればviewAの設定値変更と、viewAで設定更新処理を行う。

```Objective-C:ViewAController.h
#import <UIKit/UIKit.h>

@interface ViewAController : UIViewController
@property NSInteger iParam;
-(void)setupMethod;
@end
```
```Objective-C:ViewAController.m
#import "ViewAController.h"

@interface ViewAController ()

@end

@implementation ViewAController
...中略...
-(IBAction)myUnwindAction:(UIStoryboardSegue *)unwindSegue towardsViewController:(UIViewController *)subsequentVC{
}
*/
@end
```

```Objective-C:ViewBController.m
#import "ViewAController.h"
#import "ViewBController.h"

@interface ViewBController ()

@end

@implementation ViewBController
...中略...
//パラメータのセット(option)
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    //    if ([segue.identifier isEqualToString:@"myRewindSegue"]) {//ここでB4でつけた名前を用いる。
    ViewAController *vcA=(ViewAController*)segue.destinationViewController;
    vcA.iParam=123;//viewAの変数に値をセット
    [vcA setupMethod];//viewAの更新処理を呼び出す
}
@end
```
###処理例 (Swift)

```ViewController_A.swift
import UIKit

class ViewController_A: UIViewController {
    var iParam:  NSInteger = 0

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    func setupMethod(){}
    @IBAction func myUnwindAction(unwindSegue: UIStoryboardSegue){
   if(unwindSegue.identifier=="myRewindSegue"){
        }
    }
}
```

``` ViewController_B.swift
import UIKit

class ViewController_B: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if (segue.identifier=="myRewindSegue") {//ここでB4でつけた名前を用いる。
            let vcA = segue.destination as! ViewController_A;// destinationViewController;
            vcA.iParam=123;//viewAの変数に値をセット
            vcA.setupMethod();//viewAの更新処理を呼び出す
        }
    }
}
```

##参考iOS8
### 画面遷移（進む）の設定手順
同じ

###画面遷移（戻る）（ボタン）の設定手順
1.StoryboardのViewBに「戻るボタン」を設置
2.ViewAに戻り先のメソッドを定義
　`- (IBAction)xxxReturnAction:(UIStoryboardSegue *)segue{}`
3. ViewBの戻るボタンをCtrl+ドラッグして矢印を出し、ViewBのExitで離す。
　　さきほどのメソッドを選択

###画面遷移（戻る）（コマンド）の設定手順
1.ViewAに戻り先のメソッドを定義
　`- (IBAction)xxxReturnAction:(UIStoryboardSegue *)segue{}`
2.ViewBから"Exit"を選択し、UtilitiesペインのConnections inspector(→)を表示
3.[xxxReturnActionが現れる]
  xxx_segueの右の(＋)をドラッグし、ViewAの[ビューコントローラ]に接続
4.[manualが現れる]
　Inspector(=v=)を表示。
　identifierにsegueの名前をつける(yyySegue)
5.ボタンアクションなどに遷移アクションを記述
 `[self performSegueWithIdentifier:@“yyyySegue" sender:self];`

##参考２ パラメータを渡す
次の順序で実行されるのでその中に記載する
1.遷移元ビュー（現在表示中のビュー）のViewControllerの`canPerformUnwindSegueAction:fromViewController:withSender:`メソッドの呼び出し
2.遷移元ビューのViewControllerの`prepareForSegue:sender:`メソッドの呼び出し
3.Unwind Segueで設定された遷移先ビューのアクションメソッドの呼び出し
4.セグエ実行

```遷移元ViewController
//canPerformUnwindSegueAction:fromViewController:withSender:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
//ここでパラメータをセット
}
```

```遷移先ViewController
//iOS8
- (IBAction)xxxReturnAction:(UIStoryboardSegue *)segue{
//ここでパラメータを受け取る
}
```

### 編集履歴
2020.11.02 swift 参考コードに誤り(override 不要)
　画面遷移（戻る）の設定手順　unwindForSegue:towardsViewController:を定義する