104

私は iOS 開発に初めて足を踏み入れたところです。最初にやらなければならなかったことの 1 つは、カスタム コンテナー ビュー コントローラーを実装するSideBarViewControllerことです。これは、標準のTab Bar Controllerとほぼ同じです。(これはほとんどタブ バー コントローラーですが、タブ バーの代わりにサイド メニューを非表示にできます。)

Apple ドキュメントの指示に従ってaddChildViewController、子 ViewController をコンテナーに追加するたびに呼び出します。によって表示されている現在の子View Controllerを交換するための私のコードは、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;
}

...その後、私が知る限り、私のアプリはまだ完全に動作します!

addChildViewControllerApple のドキュメントは、何が機能するのか、なぜそれを呼ぶべきなのかについてあまり明らかにしていません。UIViewControllerクラス リファレンスのセクションでメソッドが何を行うか、またはなぜメソッドを使用する必要があるかについての関連説明の全範囲は、現時点では次のとおりです。

指定されたView Controllerを子として追加します。... このメソッドは、カスタム コンテナ ビュー コントローラの実装によってのみ呼び出されることを意図しています。このメソッドをオーバーライドする場合は、実装で super を呼び出す必要があります。

同じページの前にこの段落もあります。

コンテナ ビュー コントローラは、子のルート ビューをビュー階層に追加する前に、子ビュー コントローラをそれ自体に関連付ける必要があります。これにより、iOS はイベントを子ビュー コントローラーとそれらのコントローラーが管理するビューに適切にルーティングできます。同様に、ビュー階層から子のルート ビューを削除した後、その子ビュー コントローラーをそれ自体から切断する必要があります。これらの関連付けを作成または解除するために、コンテナーは基本クラスで定義された特定のメソッドを呼び出します。これらのメソッドは、コンテナー クラスのクライアントによって呼び出されることを意図していません。それらは、期待される封じ込め動作を提供するために、コンテナーの実装によってのみ使用されます。

呼び出す必要がある可能性のある重要なメソッドを次に示します。

addChildViewController:
removeFromParentViewController
willMoveToParentViewController:
didMoveToParentViewController:

しかし、それが話している「イベント」または「予想される封じ込め動作」が何であるか、またはこれらのメソッドを呼び出すことがなぜ(またはいつ)「不可欠」であるかについての手がかりは提供されません.

Apple ドキュメントの「カスタム コンテナ ビュー コントローラ」セクションにあるカスタム コンテナ ビュー コントローラの例はすべてこのメソッドを呼び出しているため、子 ViewController を配列にポップするだけでなく、いくつかの重要な目的に役立つと思いますが、わかりませんその目的は何か。このメソッドは何をするのでしょうか? なぜこのメソッドを呼び出す必要があるのでしょうか?

4

4 に答える 4

97
于 2013-08-26T21:34:03.837 に答える
10

-[UIViewController addChildViewController:]viewController(親)が参照を保持したいviewControllerの配列に、渡されたview Controllerを追加するだけです。これらの viewController のビューは、別のビュー (parentViewController のビューなど) のサブビューとして追加することで、実際に画面に追加する必要があります。ストーリーボードで childrenViewControllers を使用するための Interface Builder の便利なオブジェクトもあります。

以前は、ビューを使用した他の viewController の参照を保持するには、@properties で手動でそれらの参照を保持する必要がありました。のような組み込みプロパティを持つことは、childViewControllersそのparentViewControllerような相互作用を管理し、iPad アプリで見られる UISplitViewController のような構成された viewController を構築するための便利な方法です。

さらに、childrenViewControllers は、親が受け取るすべてのシステム イベント (-viewWillAppear、-viewWillDisappear など) も自動的に受け取ります。以前は、「childrenViewControllers」でこのメソッドを手動で呼び出す必要がありました。

それでおしまい。

于 2013-06-19T13:16:07.357 に答える