Help us understand the problem. What is going on with this article?

なぜ、ModalViewを戻るときにSegueでつないではいけないのか

More than 1 year has passed since last update.

遊園地とかで写真頼んだとき、撮ってもらった写真がひどくても、あーいい感じですって言っちゃいがち。
どうもこんにちは、TOSHです!

仕事柄、中高生に対してプログラミングを教えることが多いのですが、そのときよくみるのがこちらの光景です。
スクリーンショット 2019-02-23 15.27.52.png
ちなみに、Segueは全てPresent Modallyでつないであります。
うーん🤔、ありがちですね...

では、そもそもなんでこれはダメなのでしょうか???

大きく分けて、理由は二つあります

1. 次々にModalが立ち上がるために、メモリ的に無駄が生じる

このように、次々にMordalを立ち上げていくため、画面上ではふたつの画面を行き来しているようにしか見えませんが、実際は下の図のような状態になっています。
スクリーンショット 2019-02-23 15.45.00.png
透明な四角は全てViewとなっています。うーん、無駄ですねぇ。

中高生に教えるときは、このように教えていますが、実はもう一つ、これをやってはいけない大きな理由があります。
それは...

2. 戻ってきたViewは、さっきまでいたViewと違う(違うインスタンスであるということ)

まあ、本質的なことを言ってしまうと、1も2も同じような意味なきもしますが、そこは勘弁してください。

では、 これがどういう意味なのかを説明していこうと思います。
まず、最初の画面でAddボタンを5回押します。
スクリーンショット 2019-02-23 15.58.48.png
そして次の画面に行きます。
スクリーンショット 2019-02-23 16.01.59.png
そして、戻るボタンを押します。
この時、数字が5になっていて欲しいですよね...
スクリーンショット 2019-02-23 16.02.54.png
あれ?5ではなく、0になってしまっていますね。
インスタンスが生成されることによってこのようなことが起こってしまうのです。
最初に呼ばれていたものを、戻ってきた画面は違う画面なのです。
もう少しわかりやすい図にしてみましょう。
遷移を図にすると以下のようになります。
スクリーンショット 2019-02-23 16.08.56.png
本来、AとCは一緒のものではないといけないのに、違うものになってしまっているのです。

ちょっと詳しい話

正確にいうと、AとCは元は同じViewControllerなのですが、そこから紐づいて呼び出されるSwiftファイルが違うインスタンスになってしまっているいるということなのです。

では一体どうすればいいのか?

ModalViewを出したなら、そのModalViewをしまってしまえばいいのです。
そのコードがこちら

self.dismiss(animated: true, completion: nil)

ちなみに、animatedの方をfalseに変更すると画面遷移のアニメーションがoffになります。

これに変更して実行すると以下のようになります。

このようにできれば、大丈夫です。
何か、間違い等あればご指摘お願いします。

tosh_3
iOSのアプリをメインとして作っています。 最近は、Androidや暗号理論なんかも
zozotech
70億人のファッションを技術の力で変えていく
https://tech.zozo.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away