もう懐かしい話となってしまいますが、UITableViewControllerやUICollectionViewController、WebViewを全画面で配置する際には、上端と下端をLayout Guide ではなく UIViewControllerのrootの view全体に 対するConstraintsを追加する必要があります。
これによって、UITableView、UICollectionView、UIScrollView、UIWebViewがUINavigationBar、UITabBar、UIToolBarの下に潜り込み(automaticallyAdjustsScrollViewInsetsがオンの場合)、透過されたBarの下にも表示されるようになります。
ただ、automaticallyAdjustsScrollViewInsetsは Child View Controller に対しては働かないという弱点があります。Child View Controllerとは、View Controllerの中にView Controllerを埋め込んでいる状態です。例えば、 UIPageViewContorller やInterface Builder上で指定できる Container View を使った場合はこの状態になります。
そこで、Layout Guideのある一番親のViewControllerまでさかのぼって、Layout Guideの幅をゲットし、それをUIScrollViewにセットするスニペットを使っています。
+ (void)setupInsetForScrollView:(UIScrollView *)scrollView onChildViewController:(UIViewController *)viewController
{
if (!viewController.automaticallyAdjustsScrollViewInsets) {
return;
}
UIViewController *currentViewController = viewController;
UIViewController *rootParentViewController;
while (currentViewController.parentViewController) {
currentViewController = currentViewController.parentViewController;
if ([currentViewController isKindOfClass:[UITabBarController class]] ||
[currentViewController isKindOfClass:[UINavigationController class]] ||
[currentViewController isKindOfClass:[UIPageViewController class]]) {
continue;
}
rootParentViewController = currentViewController;
}
if (!rootParentViewController) {
return;
}
// http://stackoverflow.com/a/21541533/1474113
CGFloat topLength = rootParentViewController.edgesForExtendedLayout & UIRectEdgeTop ?
rootParentViewController.topLayoutGuide.length : 0;
CGFloat bottomLength = rootParentViewController.edgesForExtendedLayout & UIRectEdgeBottom ?
rootParentViewController.bottomLayoutGuide.length : 0;
UIEdgeInsets insets = UIEdgeInsetsMake(topLength, 0.0, bottomLength, 0.0);
scrollView.contentInset = scrollView.scrollIndicatorInsets = insets;
}
これをChild View Controllerからこんな感じでviewWillLayoutSubviewsの時に呼び出せば自動調整されます・・!
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
[YPLayoutGuideHelper setupInsetForScrollView:self.collectionView onChildViewController:self];
}
※UIWebViewの場合はwebView.scrollViewを渡してください!