🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

2回答

1623閲覧

【Swift】willMove removeFromParent removeFromSuperview のコード上の必要性

beginner_Jiro

総合スコア10

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2021/03/19 01:37

お世話になっております。サイドメニュー実装時のサンプルコードにて表題にございます関数の必要性の理解にいたらないためにご相談させていただきます。

疑問点とコード

サイドメニュー表示の際にNavigationControllerを使用してStoryBoard上でButtonを配置したのちにIBActionでコードに紐付け、ボタンが押された際にサイドメニューが表示されていれば閉じる。されていなければサイドメニューを表示させるといった処理を行っているのですが、非表示の際に行われる処理に意味がわかりません。

◆下記コード

//一部省略 let sidemenuViewController = SideMenuViewController() let contentViewController = UINavigationController(rootViewController: UIViewController()) //IBActionでボタンが押下された際の処理 @IBAction func MenuButtonPusshed(_ sender: Any) { if sidemenuViewController.contentRatio == 0{ showsidemenu(animated: true) } else { hideSidemenu(animated: true) } } //分岐が表示に入った際 private func showsidemenu(contentAvailavility:Bool = true,animated: Bool) { addChild(sidemenuViewController) sidemenuViewController.view.autoresizingMask = .flexibleHeight sidemenuViewController.view.frame = contentViewController.view.bounds view.insertSubview(sidemenuViewController.view, aboveSubview: contentViewController.view) sidemenuViewController.didMove(toParent: self) if contentAvailavility{ sidemenuViewController.showContentView(animated: animated) } } //分岐が非表示に入った際※解らない箇所 private func hideSidemenu(animated: Bool) { // if !isShownSidemenu { return } sidemenuViewController.hideContentsView(animeted: animated,completion: { (_) in self.sidemenuViewController.willMove(toParent: nil) self.sidemenuViewController.removeFromParent() self.sidemenuViewController.view.removeFromSuperview() }) } //一部省略

上記コードにて分岐が非表示に入った際、sidemenuViewControllerで持っているhideContentsView関数にクロージャー引数として渡している三つのwillMove、removeFromParent、removeFromSuperviewは何をしているのでしょうか? showsidemenu関数内にてaddChild(sidemenuViewController)として自身のViewの子としてsidemenuViewControllerを追加しているので非表示の際にはsidemenuViewControllerの親(ここではself)をRemoveしているのか・・・?とも思ったのですが、その場合はなぜself.sidemenuViewController.view.removeFromSuperview()のみではいけないのでしょうか?
SuperViewとの関係を絶てば問題ないような気がするんですが。。。willmoveについてもドキュメントを見ましたがコンテナビューから削除された際に呼ばれます。と書いてありますが呼ばれたあとこのコードでは何してるの!?という感じでした。。。
また、上記三つの処理をコメントアウトしてもサイドメニューの表示・非表示は特に問題なく動作しましたので目に見えたこちらの処理の必要性が解らない状態です
また、sidemenuViewControllerクラスの処理は省略しております。そちらのコードも記載の必要がある場合はお申し付けいただけますと幸いです。

英語が苦手でどのドキュメントを見ても解らず。。。日本語で回答いただけるこちらで質問させていただきました。
以上になります。よろしくお願いいたします。

参考サイトにしたgithub

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TsukubaDepot

2021/03/19 02:19

参考にされた github は日本の方が管理されているようですので、まずは作者に尋ねてみてはどうでしょうか。 コードの意図を知りたいのであれば、それが一番いいと思います。
guest

回答2

0

自己解決

参考にさせていただいた投稿者の方にご返信をいただけましたので下記に記載いたします。

当質問に回答してくださった方々もありがとうございました。

下記回答

UIViewController.willMove(toParent:)
→ UIViewController.didMove(toParent:) に対して呼びます
UIViewController.removeFromParent()
→ UIViewController.addChild(_:) に対して呼びます
UIViewController.view.removeFromSuperview()
→ UIViewController.view.insertSubview(, aboveSubview:) に対して呼びます
self.sidemenuViewController.view.removeFromSuperview()のみではいけないのでしょうか?
addSubview(insertSubViews)のみでも表示そのものはできますが、
UIViewControllerのライフサイクル上addChildはしておく必要があり、addChildした場合didMoveも必要になります。
addChildせずにviewだけaddSubviewした場合に、
今回の場合MainViewControllerが表示されたり非表示化されたりなどライフサイクルイベント(viewWillAppearやviewDidDisappearなどなど他にもあります)が発生したときSidemenuViewControllerはaddChildされていない=子供ではないため、SidemenuViewControllerのライフサイクルイベントは正しく呼ばれません。
サンプルコードのSidemenuViewControllerのライフサイクルイベントを例にしますと、
表示毎にメニュー内容を動的に変更するためにAPIコールしたりその他更新したい処理があるかもしれません。
逆にライフサイクルイベントを受ける必要がないのであれば、初めからサイドメニューのviewはMainViewControllerの下で管理すれば良いと思いますが、サイドメニューという性質上考えずらい構成のためサンプルコードではViewControllerをそれぞれ別にしています。
addChildに対して何故didMoveを呼ぶ必要があるかの記事になりますが、参考になるかもしれません。よろしければ。
https://qiita.com/yimajo/items/a5e16fa0f9c332a55ccf

投稿2021/09/16 09:49

beginner_Jiro

総合スコア10

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ぱっと見た感じではメモリ解放してるだけかと。
メニューを表示した時にメニューを作成し、メニューを隠した時に解放する、というよくあるリーク対策でしょう。

本当のところは日本語のわかる作者に聞いた方が早いでしょう。

投稿2021/03/21 04:13

errolizer

総合スコア441

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問