8

複数の種類の画面を使用するアプリを作成しています。これらはすべて、独自のカスタムビューコントローラーを保証します。次のようなアプリデリゲートのメソッドを使用してwindowメインを再割り当てすることで、ビューコントローラーとそれに関連するビューを正常に切り替えています。rootViewController

- (void)changeRootViewController:(NSString *)controllerName
{
    if (controllerName == @"book") {
        rootViewController = (UIViewController *)[[BookViewController alloc] init];
        [self.window setRootViewController:rootViewController];
    } else if (controllerName == @"something_else") {
        // Use a different VC as roowViewController
    }
}

ただし、これを行う方法は、ベストプラクティスにはなり得ないようです。UINavigationController、またはUITabBarControllerを使用したくありませんrootViewController。これはこれを行うための間違った方法ですか?もしそうなら、私はこれにどのように異なるアプローチをとるべきですか?

これはどこかでカバーされていると思いましたが、(まるで)グーグルで検索したり、関連する質問を探したりしました。何かを見逃してしまったらごめんなさい!

4

2 に答える 2

10

これを行う優れた方法の 1 つは、iOS5+ の UIViewController の子 UIViewController を持つ機能を使用することです (ビュー コントローラー コンテインメントと呼ばれます)。これを詳細に説明している WWDC ビデオを見るまで、これを行う方法を理解するのに苦労しました。

簡単に言えば、一連の子View Controllerを所有する独自の親View Controllerを作成できます。この 1 つの親ビュー コントローラーは、アプリのウィンドウのルート ビュー コントローラーとして使用できます (非常に凝ったことをしている場合を除き、おそらくそうすべきです:P)。1 つのビュー コントローラーを親として機能させる (そして、子ビュー コントローラーの追加、削除、および遷移を容易にする) この方法は、UINavigationController が行うこと (Apple の意図) を思い起こさせます。これで、独自の UINavigationController のような親ビュー コントローラーを作成できますが、遷移アニメーションと UI はまったく異なります。

例として、親ビュー コントローラーの viewDidLoad に、次のように最初の子コントローラーを追加します。

self.currentlyDisplayedChildViewController = [[TheFirstViewController alloc] init];
[self addChildViewController:self.currentlyDisplayedChildViewController];
[self.view addSubview:self.currentlyDisplayedChildViewController.view];
[self.currentlyDisplayedChildViewController didMoveToParentViewController:self];

次に、次の子ビュー コントローラーへの移行を行う関数を用意します(注: この関数は、親ビュー コントローラー (UINavigationController として機能するビュー コントローラー) に属します) :

- (void)transitionToViewController:(UIViewController *)nextChildViewController
{
    [self addChildViewController:nextChildViewController];
    __weak TheParentViewController *me = self;
    [self transitionFromViewController:self.currentlyDisplayedChildViewController
                      toViewController:nextChildViewController
                              duration:1.0f
                               options:UIViewAnimationOptionTransitionFlipFromLeft
                            animations:nil
                            completion:^(BOOL finished)
                            {
                                [nextChildViewController didMoveToParentViewController:self];
                                [me.currentlyDisplayedChildViewController willMoveToParentViewController:nil];
                                [me.currentlyDisplayedChildViewController removeFromParentViewController];
                                me.currentlyDisplayedChildViewController = nextChildViewController;
                            }];
}

本当に素晴らしいことの 1 つは、すべての標準の UIViewAnimationTransition オプションを使用できる (またはアニメーション ブロックで独自のカスタム アニメーションを定義できる) ことです。さらに、向きの回転イベントは親ビュー コントローラーから子ビュー コントローラーに自動的に転送されます。これはその 1 つです。自分でカスタム ルート ビュー コントローラーを操作する際の最も厄介な問題。

「Implementing UIViewController Containment」というタイトルの WWDC2011 ビデオをご覧になることをお勧めします。

于 2012-12-15T05:15:47.350 に答える
3

それは悪い解決策ではありません。基本的に、1 つのビューをルート ビューとして設定します。別の UIViewController が必要な場合は、別のものを設定します。漏れだけは気をつけて…

  • 保持を使用してクラスのプロパティとして rootViewController を作成します。
  • この前に:

rootViewController = (UIViewController *)[[BookViewController 割り当て] init];

これを追加:

if(rootViewController){
    self.rootViewController=nil;
}

}

だからあなたは前のものを解放します。

編集 1: 1 つ: ここでの私の説明は、UINavigationController を使用したくないという事実に基づいています。

于 2011-07-25T15:13:53.463 に答える