Commit f3b6dfc5 authored by Kurt Horimoto's avatar Kurt Horimoto Committed by Commit Bot

[iOS] Move toolbar layout to BVC.

The previous implementation of ToolbarView had a constraint that
attempted to layout the view's height by constraining its bottom anchor
to kToolbarHeight away from the top layout guide provided by the BVC.
This is incorrect because when the page is scrolled, fullscreen will
translate the toolbar up so that its bottom edge is less than its
height away from the bottom of the top safe area inset.

This CL updates ToolbarView to use |intrinsicContentSize| to specify
kToolbarHeight as its minimum size (enforced via implicit compression
resistance constraints created by returning a custom value for
|intrinsicContentSize|).  The remainder of the toolbar's layout is
managed by constraints created by BVC:
1. |primaryToolbarHeightConstraint|, which accounts for the top layout
   guide's height.
2. |primaryToolbarOffsetConstraint|, which manages the vertical
   positioning of the toolbar.  When a fullscreen progress value is
   observed, BVC updates this value to move the toolbar up and down.
   Note that the height never changes.
3. Leading and trailing constraints that match that of BVC's view so
   the toolbar's width spans the entire screen.

Bug: 799907, 799117, 798496
Cq-Include-Trybots: master.tryserver.chromium.mac:ios-simulator-cronet;master.tryserver.chromium.mac:ios-simulator-full-configs
Change-Id: I6cf2c7e09d3a8324be4008f7be7c313231fabd43
Reviewed-on: https://chromium-review.googlesource.com/882135
Commit-Queue: Kurt Horimoto <kkhorimoto@chromium.org>
Reviewed-by: default avatarKurt Horimoto <kkhorimoto@chromium.org>
Reviewed-by: default avatarJustin Cohen <justincohen@chromium.org>
Reviewed-by: default avatarGauthier Ambard <gambard@chromium.org>
Cr-Commit-Position: refs/heads/master@{#532175}
parent 1ef0493b
......@@ -704,6 +704,8 @@ NSString* const kBrowserViewControllerSnackbarCategory =
// Vertical offset for fullscreen toolbar.
@property(nonatomic, strong) NSLayoutConstraint* primaryToolbarOffsetConstraint;
// Height constraint for toolbar.
@property(nonatomic, strong) NSLayoutConstraint* primaryToolbarHeightConstraint;
// Y-dimension offset for placement of the header.
@property(nonatomic, readonly) CGFloat headerOffset;
// Height of the header view for the tab model's current tab.
......@@ -939,6 +941,7 @@ bubblePresenterForFeature:(const base::Feature&)feature
@synthesize primaryToolbarCoordinator = _primaryToolbarCoordinator;
@synthesize secondaryToolbarCoordinator = _secondaryToolbarCoordinator;
@synthesize primaryToolbarOffsetConstraint = _primaryToolbarOffsetConstraint;
@synthesize primaryToolbarHeightConstraint = _primaryToolbarHeightConstraint;
@synthesize toolbarInterface = _toolbarInterface;
@synthesize imageSaver = _imageSaver;
// DialogPresenterDelegate property
......@@ -1615,6 +1618,16 @@ applicationCommandEndpoint:(id<ApplicationCommands>)applicationCommandEndpoint {
if (IsIPhoneX()) {
[self setUpViewLayout:NO];
}
// Update the toolbar height to account for the new top inset.
self.primaryToolbarHeightConstraint.constant =
[self primaryToolbarHeightWithInset];
}
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
// Update the toolbar height to account for |topLayoutGuide| changes.
self.primaryToolbarHeightConstraint.constant =
[self primaryToolbarHeightWithInset];
}
- (void)viewDidAppear:(BOOL)animated {
......@@ -2011,6 +2024,31 @@ applicationCommandEndpoint:(id<ApplicationCommands>)applicationCommandEndpoint {
}
}
// The height of the primary toolbar with the top safe area inset included.
- (CGFloat)primaryToolbarHeightWithInset {
UIView* primaryToolbar = self.primaryToolbarCoordinator.viewController.view;
CGFloat intrinsicHeight = primaryToolbar.intrinsicContentSize.height;
// If the primary toolbar is not the topmost header, it does not overlap with
// the unsafe area.
// TODO(crbug.com/806437): Update implementation such that this calculates the
// topmost header's height.
UIView* topmostHeader = [self.headerViews firstObject].view;
if (primaryToolbar != topmostHeader)
return intrinsicHeight;
// If the primary toolbar is topmost, subtract the height of the portion of
// the unsafe area.
CGFloat unsafeHeight = 0.0;
if (@available(iOS 11, *)) {
unsafeHeight = self.view.safeAreaInsets.top;
} else {
unsafeHeight = self.topLayoutGuide.length;
}
// The topmost header is laid out |headerOffset| from the top of |view|, so
// subtract that from the unsafe height.
unsafeHeight -= self.headerOffset;
return primaryToolbar.intrinsicContentSize.height + unsafeHeight;
}
- (void)addConstraintsToToolbar {
NSLayoutYAxisAnchor* topAnchor;
// On iPad, the toolbar is underneath the tab strip.
......@@ -2023,11 +2061,19 @@ applicationCommandEndpoint:(id<ApplicationCommands>)applicationCommandEndpoint {
[self.legacyToolbarCoordinator adjustToolbarHeight];
// Create a constraint for the vertical positioning of the toolbar.
UIView* primaryView = self.primaryToolbarCoordinator.viewController.view;
self.primaryToolbarOffsetConstraint =
[self.primaryToolbarCoordinator.viewController.view.topAnchor
constraintEqualToAnchor:topAnchor];
[primaryView.topAnchor constraintEqualToAnchor:topAnchor];
// Create a constraint for the height of the toolbar to include the unsafe
// area height.
self.primaryToolbarHeightConstraint = [primaryView.heightAnchor
constraintEqualToConstant:[self primaryToolbarHeightWithInset]];
[NSLayoutConstraint activateConstraints:@[
self.primaryToolbarOffsetConstraint,
self.primaryToolbarHeightConstraint,
[self.primaryToolbarCoordinator.viewController.view.leadingAnchor
constraintEqualToAnchor:[self view].leadingAnchor],
[self.primaryToolbarCoordinator.viewController.view.trailingAnchor
......
......@@ -23,10 +23,6 @@
// The view displaying the toolbar.
@interface ToolbarView : UIView
// Top anchor at the bottom of the safeAreaLayoutGuide. Used so views don't
// overlap with the Status Bar.
@property(nonatomic, strong) NSLayoutYAxisAnchor* topSafeAnchor;
// The delegate used to handle frame changes.
@property(nonatomic, weak) id<ToolbarViewFullscreenDelegate> delegate;
......
......@@ -93,7 +93,6 @@
@synthesize trailingFakeSafeAreaConstraint = _trailingFakeSafeAreaConstraint;
@synthesize leadingSafeAreaConstraint = _leadingSafeAreaConstraint;
@synthesize trailingSafeAreaConstraint = _trailingSafeAreaConstraint;
@synthesize topSafeAnchor = _topSafeAnchor;
@synthesize locationBarView = _locationBarView;
@synthesize leadingMargin = _leadingMargin;
......@@ -104,6 +103,10 @@
[self.delegate toolbarViewFrameChanged];
}
- (CGSize)intrinsicContentSize {
return CGSizeMake(UIViewNoIntrinsicMetric, kToolbarHeight);
}
#pragma mark - Public
- (void)setUp {
......@@ -342,9 +345,6 @@
// Sets the constraints for the different subviews.
- (void)setConstraints {
self.translatesAutoresizingMaskIntoConstraints = NO;
[self.bottomAnchor constraintEqualToAnchor:self.topSafeAnchor
constant:kToolbarHeight]
.active = YES;
// ProgressBar constraints.
[NSLayoutConstraint activateConstraints:@[
......
......@@ -48,6 +48,11 @@
@property(nonatomic, assign, getter=isLoading) BOOL loading;
@property(nonatomic, strong) ToolbarView* view;
// Whether the location bar inset its page margins to the safe area when it was
// set.
@property(nonatomic, assign) BOOL locationBarDidInsetLayoutMargins;
@end
@implementation ToolbarViewController
......@@ -55,6 +60,8 @@
@synthesize buttonFactory = _buttonFactory;
@synthesize buttonUpdater = _buttonUpdater;
@synthesize loading = _loading;
@synthesize locationBarDidInsetLayoutMargins =
_locationBarDidInsetLayoutMargins;
@synthesize voiceSearchEnabled = _voiceSearchEnabled;
@synthesize omniboxFocuser = _omniboxFocuser;
@synthesize dispatcher = _dispatcher;
......@@ -286,11 +293,6 @@
self.view = [[ToolbarView alloc] init];
self.view.delegate = self;
self.view.buttonFactory = self.buttonFactory;
if (@available(iOS 11, *)) {
self.view.topSafeAnchor = self.view.safeAreaLayoutGuide.topAnchor;
} else {
self.view.topSafeAnchor = self.topLayoutGuide.bottomAnchor;
}
self.view.leadingMargin = [self leadingMargin];
[self.view setUp];
......@@ -305,7 +307,18 @@
#pragma mark - Property accessors
- (void)setLocationBarView:(UIView*)locationBarView {
// Don't inset |locationBarView|'s layout margins from the safe area because
// it's being added to a FullscreenUIElement that is expected to animate
// ouside of the safe area layout guide.
if (@available(iOS 11, *)) {
self.view.locationBarView.insetsLayoutMarginsFromSafeArea =
self.locationBarDidInsetLayoutMargins;
self.locationBarDidInsetLayoutMargins =
locationBarView.insetsLayoutMarginsFromSafeArea;
}
self.view.locationBarView = locationBarView;
if (@available(iOS 11, *))
self.view.locationBarView.insetsLayoutMarginsFromSafeArea = NO;
}
- (ToolbarToolsMenuButton*)toolsMenuButton {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment