アンワインドセグエとは何ですか、またどのように使用しますか?


584

iOS 6およびXcode 4.5には、「Ungue Segue」と呼ばれる新機能があります。

巻き戻しセグエは、ストーリーボードのシーンの既存のインスタンスへの移行を可能にすることができます

Xcode 4.5のリリースノートのこの簡単なエントリに加えて、UIViewControllerにはいくつかの新しいメソッドがあるようです。

- (BOOL)canPerformUnwindSegueAction:(SEL)action fromViewController:(UIViewController *)fromViewController withSender:(id)sender
- (UIViewController *)viewControllerForUnwindSegueAction:(SEL)action fromViewController:(UIViewController *)fromViewController withSender:(id)sender
- (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier

巻き戻しセグエはどのように機能し、何に使用できますか?

回答:


1267

手短に

アンワインドセグエ(とも呼ばれる終了セグエは、(あなたは、ナビゲーションバーからナビゲーションアイテムをポップポップオーバーを閉じたりモーダルモードで表示ビューコントローラを却下しているかのよう))プッシュ、モーダルまたはポップオーバーseguesをナビゲートバックに使用することができます。その上、1つだけでなく、一連のプッシュ/モーダル/ポップオーバーセグエを実際に巻き戻すことができます。たとえば、単一の巻き戻しアクションでナビゲーション階層の複数のステップを「戻る」ことができます。

アンワインドセグエを実行するときは、アンワインド先のビューコントローラーのアクションメソッドであるアクションを指定する必要があります。

Objective-C:

- (IBAction)unwindToThisViewController:(UIStoryboardSegue *)unwindSegue
{
}

迅速:

@IBAction func unwindToThisViewController(segue: UIStoryboardSegue) {
}

このアクションメソッドの名前は、ストーリーボードで巻き戻しセグエを作成するときに使用されます。さらに、このメソッドは、アンワインドセグエが実行される直前に呼び出されます。渡されたUIStoryboardSegueパラメーターからソースビューコントローラーを取得して、セグエを開始したビューコントローラーと対話できます(たとえば、モーダルビューコントローラーのプロパティ値を取得するため)。この点で、このメソッドにはのメソッドと同様の機能がprepareForSegue:ありUIViewControllerます。

iOS 8の更新:アンワインドセグエは、表示詳細の表示など、iOS 8の適応型セグエでも機能します。

ナビゲーションコントローラーと3つの子ビューコントローラーを備えたストーリーボードがあるとします。

ここに画像の説明を入力してください

Green View ControllerからRed View Controllerに戻る(戻る)ことができます。青から緑、または緑を介して赤にくつろぐことができます。巻き戻しを有効にするには、特別なアクションメソッドを赤と緑に追加する必要があります。たとえば、以下は赤のアクションメソッドです。

Objective-C:

@implementation RedViewController

- (IBAction)unwindToRed:(UIStoryboardSegue *)unwindSegue
{
}

@end

迅速:

@IBAction func unwindToRed(segue: UIStoryboardSegue) {
}

アクションメソッドが追加されたら、[終了]アイコンをコントロールドラッグして、ストーリーボードで巻き戻しセグエを定義できます。ここでは、ボタンが押されたときに緑から赤に巻き戻したいと思います。

ここに画像の説明を入力してください

巻き戻したいビューコントローラーで定義されているアクションを選択する必要があります。

ここに画像の説明を入力してください

また、ブルーからレッドに戻ることもできます(ナビゲーションスタックでは「2ステップ先」です)。重要なのは、正しい巻き戻しアクションを選択することです。

巻き戻しセグエが実行される前に、アクションメソッドが呼び出されます。この例では、グリーンとブルーの両方からアンワインドセグエをレッドに定義しました。UIStoryboardSegueパラメータを介してアクションメソッドで巻き戻しのソースにアクセスできます。

Objective-C:

- (IBAction)unwindToRed:(UIStoryboardSegue *)unwindSegue
{
    UIViewController* sourceViewController = unwindSegue.sourceViewController;

    if ([sourceViewController isKindOfClass:[BlueViewController class]])
    {
        NSLog(@"Coming from BLUE!");
    }
    else if ([sourceViewController isKindOfClass:[GreenViewController class]])
    {
        NSLog(@"Coming from GREEN!");
    }
}

迅速:

@IBAction func unwindToRed(unwindSegue: UIStoryboardSegue) {
    if let blueViewController = unwindSegue.sourceViewController as? BlueViewController {
        println("Coming from BLUE")
    }
    else if let redViewController = unwindSegue.sourceViewController as? RedViewController {
        println("Coming from RED")
    }
}

巻き戻しは、プッシュ/モーダルセグエの組み合わせでも機能します。たとえば、モーダルセグエを備えた別の黄色のビューコントローラーを追加した場合、1つの手順で黄色から赤に戻ることができます。

ここに画像の説明を入力してください

コードからの巻き戻し

コントロールをドラッグしてビューコントローラーの出口シンボルにドラッグし、巻き戻しセグエを定義すると、新しいセグエがドキュメントアウトラインに表示されます。

ここに画像の説明を入力してください

セグエを選択して属性インスペクターに移動すると、「識別子」プロパティが表示されます。これを使用して、セグエに一意の識別子を与えます。

ここに画像の説明を入力してください

この後、アンワインドセグエは他のセグエと同じようにコードから実行できます。

Objective-C:

[self performSegueWithIdentifier:@"UnwindToRedSegueID" sender:self];

迅速:

performSegueWithIdentifier("UnwindToRedSegueID", sender: self)

12
素晴らしい答えを+1。彼らは本当にいい音ですが、同じような方法dismissViewControllerAnimated:completion:popViewControllerAnimated:同じことを達成することはできませんか?
Sam Spencer

32
もちろんできます。ただし、ストーリーボードを使用している場合、アンワインドセグエは多くの場合、少ないコードで同じことを実現できます。実際には、コードを記述せずに、モーダル表示されたビューコントローラーを閉じることができます。もちろん、コードからコントローラを閉じることが正しいことである場合はまだ多くあります。
ImreKelényi2013

7
ヘッダーファイルにアクションメソッドを追加してください。そうしないと、ストーリーボードが認識しません。
カイルC

17
以上のもう一つの利点dismissViewControllerAnimated:completion:かは、popViewControllerAnimated:あなたがに巻き戻しているビューコントローラに追加したメソッドが呼び出されることであり、あなたが提示ビューコントローラを知るための簡単な方法を持っているので、提示するビューコントローラに提示ビューコントローラのデリゲートを加えることなく終了します。
Honus

8
少し編集を提案できますか?RedViewController.mに-(IBAction)unwindTRed:(UIStoryboardSegue *)unwindSegueを配置することは「明らかに」明確ではありませんでした。これは、ストーリーボードの緑の終了ボタンの「すべて」で普遍的に利用できます。素晴らしい答えです。今度はこれを他の問題に使用します。ありがとう!
John Ballinger

166

StoryBoardで巻き戻しセグエを使用する方法に関する限り...

ステップ1)

巻き戻したいビューコントローラのコードに移動して、次のコードを追加します。

Objective-C

- (IBAction)unwindToViewControllerNameHere:(UIStoryboardSegue *)segue {
    //nothing goes here
}

Obj-Cの.hファイルでもこの​​メソッドを宣言してください

迅速

@IBAction func unwindToViewControllerNameHere(segue: UIStoryboardSegue) {
    //nothing goes here
}

ステップ2)

ストーリーボードで、巻き戻したいビューに移動し、ボタンまたはセグエをソースビューの右上にある小さなオレンジ色の「EXIT」アイコンまでドラッグするだけです。

ここに画像の説明を入力してください

「-unwindToViewControllerNameHere」に接続するオプションがあるはずです

それだけです。ボタンをタップすると、セグエがほどけます。


5
Xcode 4.5以前では、ヘッダーでIBActionを宣言する必要があることがわかりました。これがまだ当てはまるかどうかはわかりません。
Steven Fisher

2
ストーリーボードなしで、つまりプログラムでステップ2を実行する方法はありますか?ストーリーボード(インターフェースビルダー)がめちゃくちゃになっていて、アンワインドセグエ(xcodeバグ)が表示されません。
Van Du Tran、2015年

46

アンワインドセグエは、いくつかのビューコントローラーから「現在の」ビューコントローラーに到達したビューコントローラーに「戻る」ために使用されます。

ルートビューコントローラーとして何かを持っているMyNavControllerと想像してくださいA。次に、プッシュセグエを使用しBます。これで、ナビゲーションコントローラーのviewControllers配列にAとBがあり、Bが表示されます。次に、Cモーダルでプレゼンテーションします。

アンワインドseguesを使用すると、今からアンワインド「バック」できCB(つまり、モーダルモードで表示ビューコントローラを却下)は、基本的にモーダルセグエを「元に戻します」。ルートビューコントローラーに戻るまで巻きA戻し、モーダルセグエとプッシュセグエの両方を取り消すこともできます。

セグエをほどくと、バックトラックが簡単になります。たとえば、iOS 6より前は、提示されたビューコントローラーを閉じるためのベストプラクティスは、提示されたビューコントローラーを提示されたビューコントローラーのデリゲートとして設定し、カスタムデリゲートメソッドを呼び出して、presentedViewControllerを破棄することでした。面倒で複雑に聞こえますか?そうだった。だからこそ、リラックスしたセグエがいいのです。


7
dismissViewController:animated提示されたコントローラから呼び出すことができます。それを委任する必要はありません。もちろん、データを返す必要がある場合は、委任またはその他の方法が必要です。
mxcl 2013

3
dismissViewController:animated:提示されたコントローラーから呼び出すこともできますが、ヤンが述べたように、「ベストプラクティス」は実際に、提示するコントローラーでデリゲートメソッドを呼び出して実行します。
Chris Nolet、2014

36

ここで他の回答で言及しなかったのは、最初のセグエの起源がわからない場合の巻き戻しの扱い方です。これは、私にとってさらに重要な使用例です。たとえば、2つの異なるビューコントローラー(AおよびB)からモーダルに表示するヘルプビューコントローラー(H)があるとします。

AH
BH

正しいビューコントローラに戻るように、アンワインドセグエをどのように設定しますか?答えは、AB で同じ名前のアンワインドアクションを宣言することです。例:

// put in AViewController.swift and BViewController.swift
@IBAction func unwindFromHelp(sender: UIStoryboardSegue) {
    // empty
}

このようにして、アンワインドは、セグエを開始したビューコントローラー(AまたはB)を見つけて、セグエに戻ります。

言い換えると、巻き戻しアクションは、セグエがどこに来ているのかではなく、どこから来ているのかを説明していると考えてください。


2
この情報をありがとう、これを探していました。
Madhu

2
私はすでにソリューションを実装しているので、この情報について言及するのは本当に素晴らしいことです。サポートに感謝して、ここにヒントを得るまで何も起こりません
Amr Angry

これはすばらしい情報です。どうもありがとうございました!
ドミニクバイアル

24

Swift iOS:

ステップ1:このメソッドをMASTERコントローラービューに定義します。戻りたい場所:

//pragma mark - Unwind Seques
@IBAction func goToSideMenu(segue: UIStoryboardSegue) {

    println("Called goToSideMenu: unwind action")

}

ステップ2:(StoryBoard)SLAVE / CHILD EXITボタンを右クリックし、「goToSideMenu」アクションを選択してConnect to Buttonをクリックします。このボタンをクリックすると、MASTERコントローラービューに戻ります。

ここに画像の説明を入力してください ステップ3:ビルドして実行する...


1

たとえば、viewControllerBからviewControllerAに移動すると、以下のviewControllerAでデリゲートが呼び出され、データが共有されます。

@IBAction func unWindSeague (_ sender : UIStoryboardSegue) {
        if sender.source is ViewControllerB  {
            if let _ = sender.source as? ViewControllerB {
                self.textLabel.text = "Came from B = B->A , B exited"
            }
            
        }

}
  • Seague Source View Controllerを巻き戻します(出口ボタンをVCの出口アイコンに接続し、それをunwindseagueに接続する必要があります:

ここに画像の説明を入力してください

  • Seagueの巻き戻しが完了しました-> viewControllerAのTextLabelが変更されました。

ここに画像の説明を入力してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.