Commit 8bfe1f71 authored by stkhapugin@chromium.org's avatar stkhapugin@chromium.org Committed by Commit Bot

[iOS] Use autolayout to present the omnibox popup.

Makes the omnibox popup presenter use autolayout to display the
popup view controller. The correct height of the popup is then
communicated by means of intrinsicContentSize of the popup table view.

Cq-Include-Trybots: master.tryserver.chromium.mac:ios-simulator-cronet;master.tryserver.chromium.mac:ios-simulator-full-configs
Change-Id: I521adfbff62c3c42e7120fb7bb5f7f5b09bfd2b3
Bug: 821817
Reviewed-on: https://chromium-review.googlesource.com/978177Reviewed-by: default avatarMark Cogan <marq@chromium.org>
Commit-Queue: Stepan Khapugin <stkhapugin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#551326}
parent 75cb6213
...@@ -17,7 +17,6 @@ source_set("popup") { ...@@ -17,7 +17,6 @@ source_set("popup") {
"omnibox_popup_view_ios.h", "omnibox_popup_view_ios.h",
"omnibox_popup_view_ios.mm", "omnibox_popup_view_ios.mm",
"omnibox_popup_view_suggestions_delegate.h", "omnibox_popup_view_suggestions_delegate.h",
"table_view_owning.h",
] ]
deps = [ deps = [
":popup_internal", ":popup_internal",
......
...@@ -8,13 +8,11 @@ ...@@ -8,13 +8,11 @@
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
@protocol OmniboxPopupPositioner; @protocol OmniboxPopupPositioner;
@protocol TableViewOwning;
@interface OmniboxPopupPresenter : NSObject @interface OmniboxPopupPresenter : NSObject
- (instancetype)initWithPopupPositioner:(id<OmniboxPopupPositioner>)positioner - (instancetype)initWithPopupPositioner:(id<OmniboxPopupPositioner>)positioner
popupViewController: popupViewController:(UIViewController*)viewController;
(UIViewController<TableViewOwning>*)viewController;
// Updates appearance depending on the content size of the presented view // Updates appearance depending on the content size of the presented view
// controller by changing the visible height of the popup. When the popup was // controller by changing the visible height of the popup. When the popup was
......
...@@ -5,10 +5,10 @@ ...@@ -5,10 +5,10 @@
#import "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.h" #import "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.h"
#import "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_positioner.h" #import "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_positioner.h"
#import "ios/chrome/browser/ui/omnibox/popup/table_view_owning.h"
#import "ios/chrome/browser/ui/toolbar/public/toolbar_controller_base_feature.h" #import "ios/chrome/browser/ui/toolbar/public/toolbar_controller_base_feature.h"
#include "ios/chrome/browser/ui/ui_util.h" #include "ios/chrome/browser/ui/ui_util.h"
#import "ios/chrome/browser/ui/uikit_ui_util.h" #import "ios/chrome/browser/ui/uikit_ui_util.h"
#include "ios/chrome/browser/ui/util/constraints_ui_util.h"
#import "ios/chrome/browser/ui/util/named_guide.h" #import "ios/chrome/browser/ui/util/named_guide.h"
#include "ios/chrome/grit/ios_theme_resources.h" #include "ios/chrome/grit/ios_theme_resources.h"
...@@ -27,13 +27,11 @@ NS_INLINE CGFloat BottomPadding() { ...@@ -27,13 +27,11 @@ NS_INLINE CGFloat BottomPadding() {
} // namespace } // namespace
@interface OmniboxPopupPresenter () @interface OmniboxPopupPresenter ()
// Constraint for the height of the popup.
@property(nonatomic, strong) NSLayoutConstraint* heightConstraint;
// Constraint for the bottom anchor of the popup. // Constraint for the bottom anchor of the popup.
@property(nonatomic, strong) NSLayoutConstraint* bottomConstraint; @property(nonatomic, strong) NSLayoutConstraint* bottomConstraint;
@property(nonatomic, weak) id<OmniboxPopupPositioner> positioner; @property(nonatomic, weak) id<OmniboxPopupPositioner> positioner;
@property(nonatomic, weak) UIViewController<TableViewOwning>* viewController; @property(nonatomic, weak) UIViewController* viewController;
@property(nonatomic, strong) UIView* popupContainerView; @property(nonatomic, strong) UIView* popupContainerView;
@end @end
...@@ -41,83 +39,61 @@ NS_INLINE CGFloat BottomPadding() { ...@@ -41,83 +39,61 @@ NS_INLINE CGFloat BottomPadding() {
@synthesize viewController = _viewController; @synthesize viewController = _viewController;
@synthesize positioner = _positioner; @synthesize positioner = _positioner;
@synthesize popupContainerView = _popupContainerView; @synthesize popupContainerView = _popupContainerView;
@synthesize heightConstraint = _heightConstraint;
@synthesize bottomConstraint = _bottomConstraint; @synthesize bottomConstraint = _bottomConstraint;
- (instancetype)initWithPopupPositioner:(id<OmniboxPopupPositioner>)positioner - (instancetype)initWithPopupPositioner:(id<OmniboxPopupPositioner>)positioner
popupViewController: popupViewController:(UIViewController*)viewController {
(UIViewController<TableViewOwning>*)viewController {
self = [super init]; self = [super init];
if (self) { if (self) {
_positioner = positioner; _positioner = positioner;
_viewController = viewController; _viewController = viewController;
// Set up a container for presentation.
UIView* popupContainer = [[UIView alloc] init]; UIView* popupContainer = [[UIView alloc] init];
_popupContainerView = popupContainer;
popupContainer.translatesAutoresizingMaskIntoConstraints = NO; popupContainer.translatesAutoresizingMaskIntoConstraints = NO;
popupContainer.layoutMargins = UIEdgeInsetsMake(0, 0, BottomPadding(), 0);
_heightConstraint = // Add the view controller's view to the container.
[popupContainer.heightAnchor constraintEqualToConstant:0];
_heightConstraint.active = YES;
CGRect popupControllerFrame = viewController.view.frame;
popupControllerFrame.origin = CGPointZero;
viewController.view.frame = popupControllerFrame;
[popupContainer addSubview:viewController.view]; [popupContainer addSubview:viewController.view];
viewController.view.translatesAutoresizingMaskIntoConstraints = NO;
AddSameConstraintsToSidesWithInsets(
viewController.view, popupContainer,
LayoutSides::kLeading | LayoutSides::kTrailing | LayoutSides::kBottom |
LayoutSides::kTop,
ChromeDirectionalEdgeInsetsMake(0, 0, BottomPadding(), 0));
// Add a shadow.
UIImageView* shadowView = [[UIImageView alloc] UIImageView* shadowView = [[UIImageView alloc]
initWithImage:NativeImage(IDR_IOS_TOOLBAR_SHADOW_FULL_BLEED)]; initWithImage:NativeImage(IDR_IOS_TOOLBAR_SHADOW_FULL_BLEED)];
[shadowView setUserInteractionEnabled:NO]; [shadowView setUserInteractionEnabled:NO];
[shadowView setTranslatesAutoresizingMaskIntoConstraints:NO]; [shadowView setTranslatesAutoresizingMaskIntoConstraints:NO];
[popupContainer addSubview:shadowView]; [popupContainer addSubview:shadowView];
[NSLayoutConstraint activateConstraints:@[
[shadowView.leadingAnchor // On iPhone, the shadow is on the top of the popup, as if it's cast by
constraintEqualToAnchor:popupContainer.leadingAnchor], // the omnibox; on iPad, the shadow is cast by the popup instead, so it's
[shadowView.trailingAnchor // below the popup.
constraintEqualToAnchor:popupContainer.trailingAnchor], AddSameConstraintsToSides(shadowView, popupContainer,
]]; LayoutSides::kLeading | LayoutSides::kTrailing);
AddSameConstraintsToSides(
if (IsIPadIdiom()) { shadowView, popupContainer,
[shadowView.bottomAnchor IsIPadIdiom() ? LayoutSides::kBottom : LayoutSides::kTop);
constraintEqualToAnchor:popupContainer.bottomAnchor]
.active = YES;
} else {
[shadowView.topAnchor
constraintEqualToAnchor:viewController.view.topAnchor]
.active = YES;
}
_popupContainerView = popupContainer;
} }
return self; return self;
} }
- (void)updateHeightAndAnimateAppearanceIfNecessary { - (void)updateHeightAndAnimateAppearanceIfNecessary {
UIView* popup = self.popupContainerView; UIView* popup = self.popupContainerView;
BOOL newlyAdded = ([popup superview] == nil); if (!popup.superview) {
[[self.positioner popupParentView] addSubview:popup];
[[self.positioner popupParentView] addSubview:popup];
if (newlyAdded) {
[self initialLayout]; [self initialLayout];
} }
CGFloat currentHeight = popup.bounds.size.height; if (!IsIPadIdiom()) {
if (IsIPadIdiom()) {
// Show |result.size| on iPad.
CGFloat height = [[self.viewController tableView] contentSize].height;
UIEdgeInsets insets = [[self.viewController tableView] contentInset];
// Note the calculation |insets.top * 2| is correct, it should not be
// insets.top + insets.bottom. |insets.bottom| will be larger than
// |insets.top| when the keyboard is visible, but |parentHeight| should stay
// the same.
CGFloat iPadHeight = height + insets.top * 2 + BottomPadding();
self.heightConstraint.constant = iPadHeight;
} else {
self.heightConstraint.active = NO;
self.bottomConstraint.active = YES; self.bottomConstraint.active = YES;
} }
if (currentHeight == 0) { if (popup.bounds.size.height == 0) {
// Animate if it expanding. // Animate if it expanding.
[UIView animateWithDuration:kExpandAnimationDuration [UIView animateWithDuration:kExpandAnimationDuration
delay:0 delay:0
...@@ -127,19 +103,12 @@ NS_INLINE CGFloat BottomPadding() { ...@@ -127,19 +103,12 @@ NS_INLINE CGFloat BottomPadding() {
} }
completion:nil]; completion:nil];
} }
// Set the size the table view.
CGRect popupControllerFrame = self.viewController.view.frame;
popupControllerFrame.size.height = popup.frame.size.height - BottomPadding();
self.viewController.view.frame = popupControllerFrame;
} }
- (void)animateCollapse { - (void)animateCollapse {
UIView* retainedPopupView = self.popupContainerView; UIView* retainedPopupView = self.popupContainerView;
self.heightConstraint.constant = 0;
if (!IsIPadIdiom()) { if (!IsIPadIdiom()) {
self.bottomConstraint.active = NO; self.bottomConstraint.active = NO;
self.heightConstraint.active = YES;
} }
[UIView animateWithDuration:kCollapseAnimationDuration [UIView animateWithDuration:kCollapseAnimationDuration
...@@ -160,7 +129,6 @@ NS_INLINE CGFloat BottomPadding() { ...@@ -160,7 +129,6 @@ NS_INLINE CGFloat BottomPadding() {
UIView* popup = self.popupContainerView; UIView* popup = self.popupContainerView;
// Creates the constraints if the view is newly added to the view hierarchy. // Creates the constraints if the view is newly added to the view hierarchy.
// On iPad the height of the popup is fixed. // On iPad the height of the popup is fixed.
self.heightConstraint.constant = 0;
// This constraint will only be activated on iPhone as the popup is taking // This constraint will only be activated on iPhone as the popup is taking
// the full height. // the full height.
......
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
#import "ios/chrome/browser/ui/commands/omnibox_suggestion_commands.h" #import "ios/chrome/browser/ui/commands/omnibox_suggestion_commands.h"
#import "ios/chrome/browser/ui/omnibox/autocomplete_result_consumer.h" #import "ios/chrome/browser/ui/omnibox/autocomplete_result_consumer.h"
#import "ios/chrome/browser/ui/omnibox/image_retriever.h" #import "ios/chrome/browser/ui/omnibox/image_retriever.h"
#import "ios/chrome/browser/ui/omnibox/popup/table_view_owning.h"
@protocol ImageRetriever; @protocol ImageRetriever;
...@@ -21,9 +20,7 @@ ...@@ -21,9 +20,7 @@
// is the first responder, this view controller cannot receive these events. // is the first responder, this view controller cannot receive these events.
// Hence the delegation. // Hence the delegation.
@interface OmniboxPopupViewController @interface OmniboxPopupViewController
: UIViewController<AutocompleteResultConsumer, : UIViewController<AutocompleteResultConsumer, OmniboxSuggestionCommands>
OmniboxSuggestionCommands,
TableViewOwning>
@property(nonatomic, assign) BOOL incognito; @property(nonatomic, assign) BOOL incognito;
@property(nonatomic, weak) id<AutocompleteResultConsumerDelegate> delegate; @property(nonatomic, weak) id<AutocompleteResultConsumerDelegate> delegate;
......
...@@ -63,6 +63,8 @@ UIColor* BackgroundColorIncognito() { ...@@ -63,6 +63,8 @@ UIColor* BackgroundColorIncognito() {
// tapping and holding on them or by using arrow keys on a hardware keyboard. // tapping and holding on them or by using arrow keys on a hardware keyboard.
@property(nonatomic, strong) NSIndexPath* highlightedIndexPath; @property(nonatomic, strong) NSIndexPath* highlightedIndexPath;
@property(nonatomic, strong) UITableView* tableView;
@end @end
@implementation OmniboxPopupViewController @implementation OmniboxPopupViewController
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_CHROME_BROWSER_UI_OMNIBOX_POPUP_TABLE_VIEW_OWNING_H_
#define IOS_CHROME_BROWSER_UI_OMNIBOX_POPUP_TABLE_VIEW_OWNING_H_
// A protocol that can be implemented by anything that owns a table view.
@protocol TableViewOwning<NSObject>
@property(nonatomic, strong) UITableView* tableView;
@end
#endif // IOS_CHROME_BROWSER_UI_OMNIBOX_POPUP_TABLE_VIEW_OWNING_H_
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