読者です 読者をやめる 読者になる 読者になる

酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

Xamarin.iOSでUnwind Segueを使って前の画面に戻る(Storyboard使用時/プログラム編)

iOSで表示された画面はスタック構造で履歴が管理されており、pushViewController:animated:メソッドpopViewControllerAnimated:メソッドを使用することで、指定した画面へ遷移したり遷移元の画面に戻るということをしていました。

iOS 5でStoryboardが導入されるとSegueを使って指定した画面への遷移が可能になりました。iOS 6からは指定した画面へ戻る機能が追加されました*1。この指定した画面へ戻る機能のことをUnwind Segueと呼びます。

本記事では、Xamarin.iOSとStoryboardを使っている場合にどのようにして前の画面に戻せるのか紹介したいと思います。

前提情報

本記事を読むにあたり前提となる情報を先に書いておきます。Storyboardでは下図の方向でSegueを指定しています。

f:id:ch3cooh393:20141022172944p:plain

それぞれ名前を便宜上、下記の通りとします。

  1. アカウント画面 (クラス名:AccountViewController)
  2. メニュー画面 (クラス名:MenuViewController)

(1) 遷移元のViewControllerにActionメソッドを書く

まずは戻ってきたい画面のクラスに下記のActionメソッドを書きます。ここではアカウント画面に戻りたいので、AccountViewControllerクラスを開いて、下記のActionメソッドをコピペしましょう。

[Action ("backToAccountsPage:")]
public void BackToAccountsPage(UIStoryboardSegue segue)
{
    // ここには何も実装しなくていい
}

Action属性はiOS側から見たときの名前です。UIStoryboardSegue*を引数に取る必要があるので[Action ("backToAccountsPage:")]のように最後に:をつけます。全部Storyboard上で設定できると楽なのですが……

(2) Interface builderでメニュー画面のExitを選択する

次にInterface builderを開き、メニュー画面のExitを選択します。Xcode 6.1ではオレンジ色のアイコンになっています。Exitを選択すると画面の右側にPresenting Seguesの一覧が表示されます。

f:id:ch3cooh393:20141022173829p:plain

先ほどAction属性につけた名前が表示されています。下図ではbackToAccountsPage:を選択して右ドラッグしながらメニュー画面でドロップします。

f:id:ch3cooh393:20141022174017p:plain

Menu Sceneに下図のようにUnwind segue to Scene Exit Placeが追加されました。

f:id:ch3cooh393:20141022174038p:plain

NOTE: どうでも良いことですが、先日までXamarin StudioのiOS Designerを使ってstoryboardを書いていたわけなのですが、Xcode 6.1をインストールしてから調子が悪くなってしまい、とうとうstoryboardがiOS DesignerでもXcode Interface builderでも開けなくなって爆死しました。

(3) Unwind SegueにIdentifier(名前)を付けます

戻る時に使用するSegue(Unwind Segue)に名前をつけます。ここでは下図のようにBackToAccountsPageと名前をつけています。

f:id:ch3cooh393:20141022174111p:plain

以上で、アカウント画面に戻るための準備は完了しました。

(4) MenuViewController側で任意のタイミングでUnwind Segueを実行する

ここからは任意のタイミングでアカウント画面に戻る方法を紹介します。

例えば、アカウント情報が足りていない場合に、遷移元であるアカウント画面に戻す場合には下記のようにPerformSegueメソッドを実行します。先ほど設定したBackToAccountsPageというSegueを実行しています。

public override void ViewDidAppear(bool animated)
{
    base.ViewDidAppear(animated);

    if (Account == null)
    {
        PerformSegue("BackToAccountPage", this);
        return;
    }
}

終わり。

あ、Storyboard上のViewのIBActionと紐づけることでコードを書かずに遷移元の画面に戻るということも可能なのです。さらにモーダル画面から更に前の前の画面に戻るといったようなこともできたはずです。

*1:確かiOS 6だったと思う…