Last active
April 20, 2020 15:07
-
-
Save ypresto/2f448ff5ec3a9f8ba637 to your computer and use it in GitHub Desktop.
Apply automaticallyAdjustsScrollViewInsets in child view controller like Container View or UIPageViewController
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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