iOSプログラミング:iOS11のStoryboardのSegueの使い方(2018年版)

iOS11の対応で、手持ちのアプリの従来のSegue関係のコードのところが単なるDeprecatedのウォーニングで済まずにエラーになってしまい、とりあえず昨年はエイヤで対処はしたものの、もやもやしているので整理してみました。
ネットもチェックしたのですが、Segueによる画面遷移の書き方に関して古い記述が多いのも整理した動機にあります。

これはSegueの種類を選ぶポップアップですが、下半分が古いSegueで、全滅なのがよくわかります。
それでは、例として超シンプルなアプリを紹介します。

シングルViewでプロジェクトを作成して、もうひとつUIViewController(右)を作成し、左のUIViewControllerで「次へ」がタップされると右のUIViewControllerに遷移し、「戻る」がタップされると右から左に遷移するだけのシンプルなアプリです。
 
1)親から子へ遷移
「次へ」ボタンからCtrl+ドラッグで右のUIViewControllerへドロップするとSegueができます。種類は一旦ここでは「Show e.g. Push」を選びます。これだけでノンプログラミングで左から右に遷移するようにできます。遷移だけならタップに対するActionも書かなくてOK。この程度の振る舞いであれば、以前のようにSegueのIdentifierプロパティにユニークな名前つけてメソッド呼ぶ必要はないです。Segueのイベントは暗黙でタップになります。
 
2)子から親へ戻る遷移
次に戻り方です。先ほどと同じ方法で逆方向にSegueを作ってはいけません。先ほどのSegueを逆に遷移させる、つまりunwindさせることで遷移できます。
この状態でunwindを設定するために右のUIViewControllerのexit印に「戻る」ボタンからCtrl+ドラッグで紐付けようとしても引けません。

これを紐づけるにはまず親である左のUIViewControllerにUIStoryboardSegueクラスのIBActionを定義します。
ViewController.h

- (IBAction)myUnwindAction:(UIStoryboardSegue*)unwindSegue;

ViewController.m

- (IBAction)myUnwindAction:(UIStoryboardSegue*)unwindSegue{
  NSLog( @"Unwinded" );
}

上記のmyUnwindActionに親に戻ってきた直後の処理を書くこともできます。ここではNSLogでログだけ吐かせています。
これを書いてから先ほどのexit印に「戻る」ボタンからCtrl+ドラッグで紐付けをやろうとすると、myUnwindActionが選べるようになります。親のUIViewControllerにコードで定義して、Storyboardの子で選ぶというのがわかりずらいかも。親から複数のUIViewControllerに遷移して、親に戻ってきた直後の処理が異なる時は同じように親のUIViewControllerに異なる名前で複数追加すれば、その中から選べます。
紐づけると上記の定義以外はノンコーディングで完成。
この場合のSegueのイベントも暗黙でタップになります。
 
3)遷移直前の処理を書く
親から子に遷移する時も、子から親に戻る遷移も、遷移前のUIViewControllerのボタンにActionを追加してコードを書けば、遷移直前の処理が追加できます。AppDelegateでUIViewController間で共有しているオブジェクトを更新したり、アプリのNSUserDefaultsを更新したりといったことができます。

問題点
今回の実装方法で、ひとつおかしな挙動があります。
今回のSegueは「Show e.g. Push」という種類で、下記のアイコンのとおり右から左に画面が入り込んでくるのが正しい挙動です。

ところが、今回の実装だと何故か下から上にポップアップしてしまいます。バグなのかNavigation Barがないから下から上という仕様なのか微妙です。
 
Segueはここからまだ奥が深いので一旦終わり。
 
参考:Apple公式 View Controller Programming Guide for iOS - Using Segues