[解決済み] addChildViewControllerは実際に何をするのですか?
質問
私はiOS開発に初めて足を踏み入れたところですが、最初にやらなければならないことのひとつは
カスタム コンテナ ビュー コントローラー
- と呼ぶことにします。
SideBarViewController
- で、表示する子ビューコントローラを入れ替えることができます。
タブバーコントローラ
. (これはかなり
タブバーコントローラ
のようなものですが、タブバーの代わりに隠すことのできるサイドメニューがあります)。
Apple のドキュメントの指示に従い、私は
addChildViewController
を呼び出します。で表示されている現在の子ビューコントローラーを入れ替えるための私のコードは
SideBarViewController
で表示されている現在の子ビューコントローラーを入れ替えるための私のコードは次のようになります。
- (void)showViewController:(UIViewController *)newViewController {
UIViewController* oldViewController = [self.childViewControllers
objectAtIndex:0];
[oldViewController removeFromParentViewController];
[oldViewController.view removeFromSuperview];
newViewController.view.frame = CGRectMake(
0, 0, self.view.frame.size.width, self.view.frame.size.height
);
[self addChildViewController: newViewController];
[self.view addSubview: newViewController.view];
}
それから、私は
addChildViewController
がここで何をしているのかを理解しようとして、私は全くわからないことに気づきました。新しい
ViewController
を
.childViewControllers
という配列がありますが、何の効果もないようです。子コントローラのビューからストーリーボードに設定した子コントローラへのアクションやアウトレットは、たとえ
addChildViewController
を呼び出さなくても、ストーリーボードに設定した子コントローラのビューからのアクションやアウトレットは正常に動作しています。
確かに、もし私がコードを書き換えて
addChildViewController
を呼び出さず、代わりにこのように書くと...
- (void)showViewController:(UIViewController *)newViewController {
// Get the current child from a member variable of `SideBarViewController`
UIViewController* oldViewController = currentChildViewController;
[oldViewController.view removeFromSuperview];
newViewController.view.frame = CGRectMake(
0, 0, self.view.frame.size.width, self.view.frame.size.height
);
[self.view addSubview: newViewController.view];
currentChildViewController = newViewController;
}
...それから、私のアプリは、私の知る限り、まだ完全に動作しています!
Apple のドキュメントでは、どのような
addChildViewController
が何をするのか、またはなぜそれを呼び出すことになっているのかについて、Apple のドキュメントはあまり光を当てていません。メソッドが何をするか、またはなぜそれを使用しなければならないかについての関連する説明の全範囲が
UIViewController
クラス リファレンス
は、現時点では
指定されたビューコントローラを子として追加します。 ... このメソッドは、カスタムコンテナのビューコントローラの実装からコールされることのみを想定しています。このメソッドをオーバーライドする場合は、実装の中で super を呼び出す必要があります。
同じページの前の方にこんな段落もあります。
<ブロッククオートコンテナビューコントローラは、子ビューのルートビューをビュー階層に追加する前に、子ビューコントローラを自分自身と関連付ける必要があります。これにより、iOS は子ビューコントローラとそのコントローラが管理するビューに適切にイベントをルーティングすることができます。同様に、子ビューのルートビューをビュー階層から削除した後は、その子ビューコントローラを自分自身から切り離さなければなりません。これらの関連付けを行ったり解除したりするために、 コンテナは基底クラスで定義されている特定のメソッドをコールします。これらのメソッドは、コンテナクラスのクライアントから呼び出されることを意図したものではありません。
以下は、呼び出す必要があるかもしれない必須のメソッドです。
addChildViewControllerです。
removeFromParentViewController
willMoveToParentViewControllerを使用します。
didMoveToParentViewController:
が、このメソッドが言っている「イベント」や「期待される格納動作」が何なのか、なぜ(あるいはいつ)これらのメソッドを呼び出すことが「必須」なのかについての手がかりは何も提供されていません。
Apple のドキュメントの "Custom Container View Controllers" セクションにあるカスタム コンテナ ビュー コントローラーの例はすべてこのメソッドを呼び出しているので、単に子 ViewController を配列にポップする以上の何か重要な目的を果たすと思いますが、その目的が何であるのかがわかりません。このメソッドは何をするのでしょうか、そしてなぜ私はそれを呼び出す必要があるのでしょうか?
どのように解決するのですか?
私もこの質問には疑問を感じていました。私は WWDC 2011のセッション102 のビデオとビューコントローラーさん ブルース・D・ニロ は、このように述べています。
viewWillAppear:
,viewDidAppear:
などはaddChildViewController:
. 全てはaddChildViewController:
がすることは、 "このビューコントローラはその子である" と言うことであり、ビューの外観とは何の関係もないのです。いつ呼び出されるかは、ビューがウィンドウ階層を出入りするときと関連しています。
ということで、どうやら
addChildViewController:
の呼び出しはほとんど何もしません。呼び出しの副作用が重要な部分です。それらは
parentViewController
と
childViewControllers
の関係にあります。以下は、私が知っている副作用の一部です。
- 子ビューコントローラへの外観メソッドの転送
- 回転メソッドの転送
- (可能な限り) メモリ警告を転送する
-
一貫性のない VC 階層を回避すること、特に
transitionFromViewController:toViewController:…
で、両方のVCが同じ親を持つ必要がある場合、特に - カスタム コンテナ ビュー コントローラが状態の保存と復元に参加することを許可する。
- レスポンダチェーンに参加する
-
レスポンダのフックアップ
navigationController
,tabBarController
などのプロパティ
関連
-
iOSコンパイルポッドでエラー CocoaPods could not find compatible versions for pod "XXXXX" が報告される。
-
[解決済み] App Storeのアプリと連動させる方法
-
[解決済み] iOS 8 UITableViewのセパレータインセット0が機能しない件
-
[解決済み] iOS - UITextFieldの外側をタッチするとキーボードが外れる。
-
[解決済み] UIImageのサイズを変更する最も簡単な方法?
-
[解決済み] Swiftの配列を文字列に変換するには?
-
[解決済み] セキュリティで保護されたWebサービスにもアクセスするiOSアプリで、Facebook認証を行うためのデザイン
-
[解決済み] iPhoneでナビゲーションバーを1ページ目だけ非表示にする
-
[解決済み] ナビゲーションコントローラスタック、サブビュー、モーダルコントローラを使用せずに、ビューコントローラの変化をアニメーション化する?
-
[解決済み] iOS 5でView Controller Containmentはどのように機能するのか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] アトミック属性と非アトミック属性の違いは何ですか?
-
[解決済み] フレームワークを使用したiOSアプリがデバイス上でクラッシュ、dyld: ライブラリがロードされない、Xcode 6 Beta
-
[解決済み] NSの接頭辞はどういう意味ですか?
-
[解決済み] UITextViewのマージン/パディングをなくす方法
-
[解決済み] UIButtonのタイトルを左揃えにするにはどうしたらよいですか?
-
[解決済み] アプリのプレビュー用にiOSシミュレータのビデオをキャプチャー
-
[解決済み] 16進カラーバリューの使用方法
-
[解決済み] iOS 11、Apple TV 4Kなどを搭載したXcode 9でワイヤレスデバッグを行う方法とは?
-
[解決済み] Swiftで配列に要素を追加する
-
[解決済み] Cocoapods警告 - CocoaPodsがプロジェクトの基本構成を設定しなかった理由は、プロジェクトに既にカスタム構成が設定されているためです。