8519


iPhoneアプリを製作中です。

遷移元を画面A、遷移先を画面Bとします。現在の目標は、この二つの画面を  
お互いに Segue でループさせることです。画面Bは CollectionView です。

画面Aに配置したボタンをタップすると、ポップアップメニューが出てきます。  
その中のメニューの一つに画面遷移用のボタンを実装しました。  
実装方法は以下の通りです。[Ryusuke Fuda's Tech Blog - iOS
Segueを使わずにコードで画面遷移](http://salvador.hatenablog.jp/entry/2014/04/27/164132)を参考にしました。

  1. 遷移先の storyboad の Identity で、 **Use Storyboad ID** にチェックを入れる
  2. Storyboad ID に遷移先のクラス名を入力する
  3. 遷移元のヘッダファイルに、遷移先のヘッダファイルをインポートする
  4. 遷移元の、画面遷移用ボタンに以下のコードを書き込む

[code]

    GamenBViewController *controller =
    [self.storyboard     instantiateViewControllerWithIdentifier:@"GamenBViewController"];
    [self presentModalViewController:controller animated:YES]; //モーダルで呼び出す
    
[/code]

上記内容で画面 A から画面 B に遷移させました。

画面 B から画面 A には以下の内容で遷移させます。  
※ showDetail は Segue の名前です

[code]

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
       if ([[segue identifier] isEqualToString:@"showDetail"]) {
         NSIndexPath *indexPath = [self.collectionView indexPathForCell:sender];
        UIImage *img = _objects[indexPath.row];
        [[segue destinationViewController] setDetailItem:img];   
       }
    }
    
[/code]

画面 A から画面 B に遷移させる内容を実装すると、なぜかそれまでは上手くいっていたはずの、  
画面 B から画面 A への遷移がエラーになってしまいます。  
エラーメッセージは以下の通りです。

> Terminating app due to uncaught exception 'NSGenericException', reason:
> 'Could not find a navigation controller for segue 'showDetail'. Push segues
> can only be used when the source controller is managed by an instance of
> UINavigationController.'

どう対処すれば良いか、どなたかご教示いただけないでしょうか。  
以上、何卒よろしくお願いいたします。


CC BY-SA 3.0
2015-03-28T15:27:21.223
8514
2015-03-29T10:50:44.757
2015-03-28T16:49:40.840
7926
7470
question
objective-c iphone xcode6
２つの画面を Segue でお互いに遷移させる為にはどうすればいいのでしょうか


エラーメッセージが教えてくれること、そのものです。すなわち`UINavigationController`が運営（Manage）している環境でなければ、`push
segues`ができないのだから、`UINavigationController`を作ってやればいいのです。

![画像の説明をここに入力](https://i.stack.imgur.com/ircnF.png)

XcodeのStoryboardで、ルートになるView Controllerを選択して、Editorメニュー＞Embed In＞Navigation
Controllerで、UINavigationControllerが作られます。  
しかし、

> 二つの画面をお互いに Segue でループさせること

というのは、むだにメモリを消費して、最悪アプリを落とすことにしかなりませんので、するべきではありません。外見は、「互いの画面を行ったり来たり」しているように見えますが、じっさいは、View
Controller Aの上に、View Controller Bがのっかり、その上にView Controller
Aがのっかるという、スタックが形成されていきます。モーダルで遷移したViewControllerは、`dismiss`で前のViewControllerに戻ること。Navigation
Controllerで遷移した場合は、`pop`するか、`Unwind
Segue`するかして、戻ることです。「戻る」という処理をすることで、遷移前のViewConttollerは、メモリから解放され、メモリを圧迫する要因ではなくなります。

さて、あなたが書いたプログラムを詳細に見ていきます。

[code]

    [self presentModalViewController:controller animated:YES]; //モーダルで呼び出す
    
[/code]

`presentModalViewController:animated:`は、iOS 6にて **Deprecated**
されているので、使うべきではありません。代わりに[`presentViewController:animated:completion:`](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/#//apple_ref/occ/instm/UIViewController/presentViewController:animated:completion:)を使ってください。  
モーダルで遷移したViewControllerから「戻る」には、[dismiss〜](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/#//apple_ref/occ/instm/UIViewController/dismissViewControllerAnimated:completion:)か、`Unwind
Segue`を使います。`Unwind
Segue`は、これをキーワードにしてネット検索すれば、ていねいな説明をしているブログがヒットしますので、それで勉強してください。なお、くれぐれもそのドキュメントが書かれた日付は、かならずチェックしてください。あまりに古い情報はそのまま受け取らないほうがいいです。


CC BY-SA 3.0
2015-03-28T17:42:58.657
8519
2015-03-29T10:50:44.757
2015-03-29T10:50:44.757
7362
7362
8514
answer