Skip to content

Instantly share code, notes, and snippets.

@ypresto
Last active April 20, 2020 15:07
Show Gist options
  • Save ypresto/2f448ff5ec3a9f8ba637 to your computer and use it in GitHub Desktop.
Save ypresto/2f448ff5ec3a9f8ba637 to your computer and use it in GitHub Desktop.
Apply automaticallyAdjustsScrollViewInsets in child view controller like Container View or UIPageViewController
//
// YPLayoutGuideHelper.m
//
// Created by Yuya Tanaka, 2015
//
// This is free and unencumbered software released into the public domain.
// Refer: http://unlicense.org/
//
// automaticallyAdjustsScrollViewInsets doesn't work for child view controllers
// hosted by something like Container View or UIPageViewController.
// This method manually setups insets from parent view controller.
//
#import "YPLayoutGuideHelper.h"
@implementation YPLayoutGuideHelper
/// Setups content inset of scroll view on child view controller.
/// Call this from viewWillLayoutSubviews of child view controller.
/// Any kind of scroll views (e.g. UITableView, UICollectionView, webView.scrollView) are accepted.
/// If passed view controller is NOT a child view controller or automaticallyAdjustsScrollViewInsets is disabled,
/// this method does nothing.
+ (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;
}
@end
//
// YPLayoutGuideHelper.swift
//
// Created by Yuya Tanaka, 2016
//
// This is free and unencumbered software released into the public domain.
// Refer: http://unlicense.org/
//
// automaticallyAdjustsScrollViewInsets doesn't work for child view controllers
// hosted by something like Container View or UIPageViewController.
// This method manually setups insets from parent view controller.
//
import Foundation
import UIKit
final class YPLayoutGuideHelper: NSObject {
/// Setups content inset of scroll view on child view controller.
/// Call this from viewWillLayoutSubviews of child view controller.
/// Any kind of scroll views (e.g. UITableView, UICollectionView, webView.scrollView) are accepted.
/// If passed view controller is NOT a child view controller or automaticallyAdjustsScrollViewInsets is disabled,
/// this method does nothing.
class func setupInsetForScrollView(scrollView: UIScrollView, onChildViewController viewController: UIViewController) {
if (!viewController.automaticallyAdjustsScrollViewInsets) {
return
}
var currentViewController = viewController
var candidateRootParentViewController: UIViewController? = nil
while let viewController = currentViewController.parentViewController {
currentViewController = viewController
if viewController is UITabBarController ||
viewController is UINavigationController ||
viewController is UIPageViewController {
continue
}
candidateRootParentViewController = viewController
}
guard let rootParentViewController = candidateRootParentViewController else { return }
// http://stackoverflow.com/a/21541533/1474113
let topLength = rootParentViewController.edgesForExtendedLayout.contains(.Top) ?
rootParentViewController.topLayoutGuide.length : 0
let bottomLength = rootParentViewController.edgesForExtendedLayout.contains(.Bottom) ?
rootParentViewController.bottomLayoutGuide.length : 0
let insets = UIEdgeInsets(top: topLength, left: 0.0, bottom: bottomLength, right: 0.0)
scrollView.contentInset = insets
scrollView.scrollIndicatorInsets = insets
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment