カスタムコンテナビューコントローラに埋め込まれると、コンテンツはナビゲーションバーの下に隠れます。質問する

カスタムコンテナビューコントローラに埋め込まれると、コンテンツはナビゲーションバーの下に隠れます。質問する

アップデート

Tim の回答に基づいて、カスタム コンテナーの一部であるスクロール ビュー (またはサブクラス) を持つ各ビュー コントローラーに次のコードを実装しました。

- (void)didMoveToParentViewController:(UIViewController *)parent
{
    if (parent) {
        CGFloat top = parent.topLayoutGuide.length;
        CGFloat bottom = parent.bottomLayoutGuide.length;

        // this is the most important part here, because the first view controller added 
        // never had the layout issue, it was always the second. if we applied these
        // edge insets to the first view controller, then it would lay out incorrectly.
        // first detect if it's laid out correctly with the following condition, and if
        // not, manually make the adjustments since it seems like UIKit is failing to do so
        if (self.collectionView.contentInset.top != top) {
            UIEdgeInsets newInsets = UIEdgeInsetsMake(top, 0, bottom, 0);
            self.collectionView.contentInset = newInsets;
            self.collectionView.scrollIndicatorInsets = newInsets;
        }
    }

    [super didMoveToParentViewController:parent];
}

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

というカスタム コンテナ ビュー コントローラがありますSegmentedPageViewController。これを として設定しますUINavigationController's rootViewController

の目的は、NavController の titleView として設定された が異なる子ビュー コントローラ間を切り替えることがSegmentedPageViewControllerできるようにすることです。UISegmentedControl

ここに画像の説明を入力してください

これらの子ビュー コントローラにはすべて、スクロール ビュー、テーブル ビュー、またはコレクション ビューのいずれかが含まれます。

最初のビュー コントローラーは正常に読み込まれ、ナビゲーション バーの下に正しく配置されていることがわかりました。しかし、新しいビュー コントローラーに切り替えると、ナビゲーション バーは考慮されず、ビューがナビゲーション バーの下に設定されます。

ここに画像の説明を入力してください

自動レイアウトとインターフェース ビルダーを使用しています。考えられるすべてのことを試しましたが、一貫した解決策が見つかりません。

以下は、最初のビュー コントローラーを設定し、ユーザーがセグメント化されたコントロールをタップしたときに別のビュー コントローラーに切り替えるメイン コード ブロックです。

- (void)switchFromViewController:(UIViewController *)oldVC toViewController:(UIViewController *)newVC
{
    if (newVC == oldVC) return;

    // Check the newVC is non-nil otherwise expect a crash: NSInvalidArgumentException
    if (newVC) {

        // Set the new view controller frame (in this case to be the size of the available screen bounds)
        // Calulate any other frame animations here (e.g. for the oldVC)
        newVC.view.frame = self.view.bounds;

        // Check the oldVC is non-nil otherwise expect a crash: NSInvalidArgumentException
        if (oldVC) {
            // **** THIS RUNS WHEN A NEW VC IS SET ****
            // DIFFERENT FROM FIRST VC IN THAT WE TRANSITION INSTEAD OF JUST SETTING


            // Start both the view controller transitions
            [oldVC willMoveToParentViewController:nil];
            [self addChildViewController:newVC];

            // Swap the view controllers
            // No frame animations in this code but these would go in the animations block
            [self transitionFromViewController:oldVC
                              toViewController:newVC
                                      duration:0.25
                                       options:UIViewAnimationOptionLayoutSubviews
                                    animations:^{}
                                    completion:^(BOOL finished) {
                                        // Finish both the view controller transitions
                                        [oldVC removeFromParentViewController];
                                        [newVC didMoveToParentViewController:self];
                                        // Store a reference to the current controller
                                        self.currentViewController = newVC;
                                    }];
        } else {

            // **** THIS RUNS WHEN THE FIRST VC IS SET ****
            // JUST STANDARD VIEW CONTROLLER CONTAINMENT

            // Otherwise we are adding a view controller for the first time
            // Start the view controller transition
            [self addChildViewController:newVC];

            // Add the new view controller view to the view hierarchy
            [self.view addSubview:newVC.view];

            // End the view controller transition
            [newVC didMoveToParentViewController:self];

            // Store a reference to the current controller
            self.currentViewController = newVC;
        }
    }

}

ベストアンサー1

カスタム コンテナ ビュー コントローラでは、子ビュー コントローラのプロパティcontentInsetを尊重しながら、既知のナビゲーション バーの高さに応じて 2 番目のビュー コントローラの高さを調整する必要がありますautomaticallyAdjustsScrollViewInsets。(コンテナのプロパティにも注目してください。topLayoutGuideビューの切り替え中および切り替え後に正しい値が返されることを確認してください。)

UIKit はこのロジックを適用する方法に著しく一貫性がなく (バグが多い)、階層内の複数のビュー コントローラーにアクセスしてこの調整を自動的に実行することが時々ありますが、多くの場合、カスタム コンテナーを切り替えた後は自分で作業を行う必要があります。

おすすめ記事