This document describes how to configure your scroll views in IB, so that their insets are configured to accomodate coverage by UINavigationBar and UITabBar.
A common reason for wanting this is to allow these views to configured as 'translucent', while scroll view content scrolls beneath them.
This guide is broken up into two types of view configurations...
- Configuration 1: A top-level scroll view, which fills
UIViewController'sview - Configuration 2: A top-level scroll view, which does not fill
UIViewController'sview
This configuration happens when your UIViewController's view is or contains a single scroll view which fills the entirety the view.
(If your UIViewController is actually a UITableViewController, only follow the IB: UIViewController settings section, and ignore the rest.)
If there are other views in the root of the view hierachy, the scroll view must be at z-index of 0 (that is, it should be the bottommost view).
Enable:
- Adjusts Scroll View Insets
- Under Top Bars
- Under Bottom Bars
Create two constraints by Control-Dragging from the scroll view instance to the UIViewController's view instance in the IB view hierarchy.
Then, holding Option, select these constraints:
- Top Space to Container Margin
- Bottom Space to Container Margin
... this yields the following Constraints on the UIViewController's view instance:
- Bottom Margin Space to: [Scroll View]
- Top Margin Space to: [Scroll View]
If you don't want the UINavigationBar to cover the top of the scroll view in the IB preview of your view, ignore the last constraint from above, and, instead, create these two constaints:
- Top Margin Space to: [Scroll View] @ 999 priority
- Top Margin Space to: [Scroll View], constant: 64, enabled:
Remove at build time
...the same can be done to prevent UITabBar coverage by appropriately inverting the parameters and objects of the above steps.
This configuration happens when your UIViewController's view contains a scroll view which does not fill the entirety of the view.
A common exammple of this configuration is if you have a header- or footer-like view that your scroll view is pinned to on the top or bottom edge.
The primary point of concern for this configuration is that automaticallyAdjustsScrollViewInsets is arguably broken, and does work as you might expect [1]. Therefore, in these scenarios, insetting will need to be implemented programmatically.
Enable:
- Under Top Bars
- Under Bottom Bars
Disable:
- Adjusts Scroll View Insets
Follow the instructions from Configuration 1.
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if let superview = tableView.superview where superview == view {
let tableViewTopContentInset = max(0, topLayoutGuide.length - CGRectGetMinY(tableView.frame))
let tableViewBottomContentInset = max(0,
bottomLayoutGuide.length - (CGRectGetHeight(superview.frame) - CGRectGetMaxY(tableView.frame)))
tableView.contentInset = UIEdgeInsets(top: tableViewTopContentInset,
left: tableView.contentInset.left,
bottom: tableViewBottomContentInset,
right: tableView.contentInset.right)
tableView.scrollIndicatorInsets = UIEdgeInsets(top: tableViewTopContentInset,
left: tableView.scrollIndicatorInsets.left,
bottom: tableViewBottomContentInset,
right: tableView.scrollIndicatorInsets.right)
}
}
[1] More information: https://openradar.appspot.com/23666782