アップデート
ティムの回答に基づいて、カスタム コンテナーの一部であるスクロールビュー (またはサブクラス) を持つ各ビュー コントローラーに次を実装しました。
- (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
。
の目的はSegmentedPageViewController
、UISegmentedControl
NavController の titleView として設定された が、異なる子ビュー コントローラ間で切り替えられるようにすることです。
これらの子ビュー コントローラーにはすべて、スクロールビュー、テーブルビュー、またはコレクション ビューのいずれかが含まれています。
最初のビュー コントローラーが正常に読み込まれ、ナビゲーション バーの下に正しく配置されていることがわかりました。しかし、新しいビュー コントローラーに切り替えると、ナビゲーション バーは無視され、ビューはナビゲーション バーの下に設定されます。
自動レイアウトとインターフェースビルダーを使用しています。考えられるすべてのことを試しましたが、一貫した解決策が見つかりません。
最初のビュー コントローラーを設定し、ユーザーがセグメント化されたコントロールをタップしたときに別のビュー コントローラーに切り替えるメインのコード ブロックを次に示します。
- (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;
}
}
}