62985


コードでモーダル画面を表示させていますが、閉じる際にdismissは表示元、表示先どちらで記載するのが正しいのでしょうか。動作的にはどちらに書いても閉じられます。

いろいろと調べていて、どちらのやり方も見つかり  
どちらが正しいのか、よく理解できないのでご質問させてください。

どちらのViewControllerでdismissを行ってもなぜモーダル画面を閉じれるのかと思っています。  
普通に考えるとself.dismiss（自分自身を閉じる）なので、モーダル画面側でdismissするという形なのでしょうか？ただ、その場合に表示元でdismissした場合は表示元が閉じられるという意味になるかなと思うのですが、なぜ表示元が閉じられないのかと思っています。

dismissの意味がわからず。下記３パターンのうちのどれかでしょうか？

・表示元が表示先を閉じる  
・表示先が自身を閉じる  
・一番上のビューを閉じる

パターン1: モーダル画面で dismiss

[code]

    class ViewController: UIViewController {
        @IBAction func didTouchShowModal(_ sender: Any) {
            let vc = self.storyboard!.instantiateViewController(identifier: "ModalViewController") as! ModalViewController
            self.present(vc, animated: true, completion: nil)
        }
    }
    class ModalViewController: UIViewController {
        @IBAction func didTouchClose(_ sender: Any) {
            self.dismiss(animated: true)
        }
    }
    
[/code]

パターン2: 表示元で dismiss

[code]

    protocol ModalViewControllerDelegate{
        func close()
    }
    
    class ViewController: UIViewController, ModalViewControllerDelegate {
        @IBAction func didTouchShowModal(_ sender: Any) {
            let vc = self.storyboard!.instantiateViewController(identifier: "ModalViewController") as! ModalViewController
            vc.delegate = self
            self.present(vc, animated: true, completion: nil)
        }
    
        func close() {
            self.dismiss(animated: true)
        }
    }
    
    class ModalViewController: UIViewController {
        var delegate: ModalViewControllerDelegate? = nil
    
        @IBAction func didTouchClose(_ sender: Any) {
            //self.dismiss(animated: true)
            self.delegate?.close()
        }
    }
    
[/code]


CC BY-SA 4.0
2020-02-12T01:40:52.270
62975
2020-02-12T05:19:43.930
2020-02-12T01:58:25.640
36965
36965
question
swift ios xcode
dismissを行うタイミングについて


この場合はどちらに書くのも正しいです。同じ動作をします。それは意図した挙動で正しいです。

> The presenting view controller is responsible for dismissing the view
> controller it presented. If you call this method on the presented view
> controller itself, UIKit asks the presenting view controller to handle the
> dismissal.

<https://developer.apple.com/documentation/uikit/uiviewcontroller/1621505-dismiss>

このように書いてある通り、`dismiss()`メソッドはモーダルビューとして表示先の子ビューコントローラを閉じます。ただし、子ビューコントローラがそれ以上モーダル表示をしていない状態で`dismiss()`を読んだ場合は、自身を表示した表示元の親ビューコントローラに処理を移譲するので、結果として表示元のビューコントローラから`dismiss()`メソッド呼ぶのと同じことになります。

子ビューコントローラ（ここでは`ModalViewController`）がさらに別のビューコントローラをモーダル表示していた場合は同じ結果にならず、その子ビューコントローラだけが閉じられます。

このとき、一番大元のビューコントローラ（ここでは`ViewController`）の`dismiss()`メソッドを読んだ場合はそれ以下のビュー（`ModalViewController`とその子ビューコントローラ）をすべて閉じます。

この挙動は複数のモーダルビューを一度に閉じたい場合に活用します。

まとめると、モーダル表示したビューコントローラが１枚の場合（表示元と表示先しかない場合）はどちらの`dismiss()`メソッドを呼んでもまったく同じ結果になります。どちらを呼ぶのも正しいです。

モーダル表示を連続して２回以上行っているときは、一番上に重なっているビューコントローラとそのすぐ下のビューコントローラについては同じ結果になります。

それ以上下のビューコントローラについては自分より上のモーダルビューをすべて閉じます。

モーダル表示したビューコントローラが１枚の場合と２枚以上の場合で分けてまとめましたが、同じことを行っているだけです。

わかりにくければ実際にコードを書いて試してみることをオススメします。


CC BY-SA 4.0
2020-02-12T05:19:43.930
62985
2020-02-12T05:19:43.930
5519
62975
answer