Permalink
Browse files

[FlexibleHeader] Fix additionalSafeAreaInsets bug when topLayoutGuide…

…AdjustmentEnabled is enabled. (#4354)

Prior to this change:

When self.topLayoutGuideAdjustmentEnabled was enabled before a tracking scroll view is set, the top layout guide behavior was adjusting the additionalSafeAreaInsets. If a tracking scroll view was then set, the additionalSafeAreaInsets were never reset, resulting in the additional safe area insets being incorrect on the topLayoutGuideViewController.

After this change:

If no tracking scroll view is set when self.topLayoutGuideAdjustmentEnabled is enabled, the topLayoutGuideViewController's additionalSafeAreaInsets is reset to 0.
  • Loading branch information...
jverkoey committed Jun 6, 2018
1 parent 2eee13c commit dc903f95ba532d3c6ffad7677f9468f7be9fb232
@@ -288,18 +288,23 @@ - (void)updateTopLayoutGuide {
CGFloat topInset = CGRectGetMaxY(_headerView.frame);
self.topLayoutGuideConstraint.constant = topInset;
// If there is a tracking scroll view then the flexible header will manage safe area insets via
// the tracking scroll view's contentInsets. Some day - in the long distant future when we only
// support iOS 11 and up - we can probably drop the content inset adjustment behavior in favor
// of modifying additionalSafeAreaInsets instead.
if (self.headerView.trackingScrollView != nil) {
return;
}
#if defined(__IPHONE_11_0) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0)
if (@available(iOS 11.0, *)) {
UIViewController *topLayoutGuideViewController = [self fhv_topLayoutGuideViewControllerWithFallback];
if (topLayoutGuideViewController != nil) {
// If there is a tracking scroll view then the flexible header will manage safe area insets via
// the tracking scroll view's contentInsets. Some day - in the long distant future when we only
// support iOS 11 and up - we can probably drop the content inset adjustment behavior in favor
// of modifying additionalSafeAreaInsets instead.
if (self.headerView.trackingScrollView != nil) {
// Reset the additional safe area insets if we are now tracking a scroll view.
if (topLayoutGuideViewController != nil) {
UIEdgeInsets additionalSafeAreaInsets =
topLayoutGuideViewController.additionalSafeAreaInsets;
additionalSafeAreaInsets.top = 0;
topLayoutGuideViewController.additionalSafeAreaInsets = additionalSafeAreaInsets;
}
} else if (topLayoutGuideViewController != nil) {
UIEdgeInsets additionalSafeAreaInsets = topLayoutGuideViewController.additionalSafeAreaInsets;
if (self.headerView.statusBarHintCanOverlapHeader) {
// safe area insets will likely already take into account the top safe area inset, so let's
@@ -77,6 +77,37 @@ class FlexibleHeaderInjectionTopLayoutGuideTests: XCTestCase {
#endif
}
func testTrackingAnUntrackedTableViewTopLayoutGuideEqualsBottomEdgeOfHeaderView() {
// Given
let contentViewController = UITableViewController()
contentViewController.addChildViewController(fhvc)
contentViewController.view.addSubview(fhvc.view)
fhvc.didMove(toParentViewController: contentViewController)
// Then
XCTAssertEqual(contentViewController.topLayoutGuide.length, fhvc.headerView.frame.maxY)
#if swift(>=3.2)
if #available(iOS 11.0, *) {
XCTAssertEqual(contentViewController.additionalSafeAreaInsets.top,
fhvc.headerView.frame.maxY - MDCDeviceTopSafeAreaInset())
XCTAssertEqual(contentViewController.tableView.adjustedContentInset.top, 0)
}
#endif
// And then when
fhvc.headerView.trackingScrollView = contentViewController.tableView
// Then
XCTAssertEqual(contentViewController.topLayoutGuide.length, fhvc.headerView.frame.maxY)
#if swift(>=3.2)
if #available(iOS 11.0, *) {
XCTAssertEqual(contentViewController.additionalSafeAreaInsets.top, 0)
XCTAssertEqual(contentViewController.tableView.adjustedContentInset.top,
fhvc.headerView.maximumHeight + MDCDeviceTopSafeAreaInset())
}
#endif
}
// MARK: Tracked table view
func testTrackedTableViewTopLayoutGuideEqualsBottomEdgeOfHeaderView() {

0 comments on commit dc903f9

Please sign in to comment.