質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.37%

presentで開いた画面を閉じ、親画面からpushで開く

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 5,355

tropfen

score 12

モーダル画面を閉じた後、下記の通り親画面からpushした画面を表示したいのですが、うまく動作させられません。

  • モーダル画面を閉じる前の状態
    topViewController -(push)-> listViewController -(present)-> modalViewController
  • モーダル画面で閉じるボタン押下後の期待する状態
    topViewController -(push)-> listViewController -(push)-> detailViewController -(push)-> editViewController

modalViewを閉じた後はeditViewが表示され、editViewで戻るボタンを押下した際はdetailViewが表示されるのが理想です。(detailViewの戻るボタンはListViewへ遷移する)

pushViewControllerのみで遷移をしていた場合、setViewControllerで強引に画面遷移の書き換えを行って遷移ができたので、応用して下記の実装で行けるかと思ったのですが、モーダル画面が閉じて終了してしまい、手詰まりの状態です。

func closeAndPush() {
    self.dismissViewControllerAnimated(true, completion: {
        var history = self.navigationController?.viewControllers
        history?.removeLast()
        if let detailView = self.storyboard?.instantiateViewControllerWithIdentifier("DetailView") as? detailViewController {
            history?.append(detailView)
            if let editView = self.storyboard?.instantiateViewControllerWithIdentifier("EditView") as? editViewController {
                history?.append(editView)
                self.navigationController?.setViewControllers(history!, animated: true)
            }
        }
    })
}


ナビゲーションのviewControllersを取る位置を変えたりなど、色々と試してはみたのですが、listViewでいずれも処理が終了してしまいます。
手段がない場合、listView以降の画面は、delegateを使用し、必ずlistViewを経由して表示を行う実装を検討しておりますが、表示上スマートではないため、できれば上記仕様を実現したく思っています。

勉強を始めたばかりで概念の部分はほとんど理解できていないのですが、実装せざるを得ない状況のため、お知恵を借りれると大変助かります。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

最低限の動作確認しかしていませんが、モーダルを閉じる処理を親のListViewControllerに記述して呼び出すことで思った通りに動作しました。

import UIKit

// TopViewController
class TopViewController: UIViewController {

    @IBAction func pushNext(sender: UIButton) {
        if let listView = self.storyboard?.instantiateViewControllerWithIdentifier("list") as? ListViewController {
            self.navigationController?.pushViewController(listView, animated: true)
        }
    }
}

// ListViewController
class ListViewController: UIViewController {

    @IBAction func pushModal(sender: UIButton) {
        if let modalView = self.storyboard?.instantiateViewControllerWithIdentifier("modal") as? ModalViewController {

            guard var history = self.navigationController?.viewControllers,
                let detilView = self.storyboard?.instantiateViewControllerWithIdentifier("detail") as? DetailViewController,
                let editView = self.storyboard?.instantiateViewControllerWithIdentifier("edit")   as? EditiewController else {
                    return
            }

            history.append(detilView)
            history.append(editView)
            modalView.editView = editView

            self.presentViewController(modalView, animated: true) {
                self.navigationController?.setViewControllers(history, animated: false)
            }
        }
    }
}

// ModalViewController
class ModalViewController: UIViewController {

    weak var editView: EditiewController!

    @IBAction func pushCloseButton(sender: UIButton) {
        // 親のViewControllerからModalを閉じる
        editView?.modalClose(self)
    }
}

// DetailViewController
class DetailViewController: UIViewController {

    @IBAction func pushNext(sender: UIButton) {
        if let editView = self.storyboard?.instantiateViewControllerWithIdentifier("edit") as? EditiewController {
            self.navigationController?.pushViewController(editView, animated: true)
        }
    }
}

// EditViewController
class EditiewController: UIViewController {

    var modalView: ModalViewController!

    func modalClose(modalView: ModalViewController) {
        modalView.dismissViewControllerAnimated(true, completion: nil)
    }
}

image

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/10 11:53

    今回はsegueは使わず全てコードから画面遷移を行っているため、適宜読み替えて試したところ、無事に遷移させることができました。
    一度ListViewControllerの画面が表示されてしまうのが気になりますが、ひとまずこちらの方法で進めたいと思います。
    大変分かりやすい回答ありがとうございました!

    キャンセル

  • 2016/06/10 13:07

    やりたい動きが分かったので、ListViewControllerも表示されないように修正しました。
    確認してみてください。

    キャンセル

  • 2016/06/10 18:05

    編集頂いた内容で動作確認が取れました。
    特殊な動きをさせようとしているのは分かっていたのですが、やはり複雑度が増しますね。
    大変勉強になりました。ありがとうございました!

    キャンセル

0

  • ナビゲーションコントローラのviewControllersを得る
  • modalViewControllerpresentingViewController(listViewController)のインスタンスを得る
  • viewControllersの配列の0からlistViewControllerのインデックスまでの要素を得る
  • 抜き出した要素の末尾にdetailViewController、editViewControllerのインスタンスを足す
  • ナビゲーションコントローラのsetViewControllers()に渡す

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.37%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る