Skip to content

Commit

Permalink
[ios] Adds support for Infobar Modal dynamic height.
Browse files Browse the repository at this point in the history
- The InfobarModal will now change its height so it can contain its content.
In case the content's height is larger than the screen we can scroll the
Modal.

Screenshot:
https://drive.google.com/open?id=1paoV27CdDMaF0tTQ8vHgvF37z0tMtv4K
https://drive.google.com/open?id=1dI725bQX5qyqu3FvgEndBIeCFCCdh0EA

Bug: 911864
Change-Id: Ie5142259f6bd6a449f2a4350875e4be41c5840d7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1575119
Commit-Queue: Sergio Collazos <sczs@chromium.org>
Reviewed-by: Chris Lu <thegreenfrog@chromium.org>
Reviewed-by: Peter Lee <pkl@chromium.org>
Cr-Commit-Position: refs/heads/master@{#653064}
  • Loading branch information
sczs authored and Commit Bot committed Apr 23, 2019
1 parent e7b4a01 commit 945f121
Show file tree
Hide file tree
Showing 12 changed files with 96 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,11 @@ - (void)infobarWasDismissed {
self.modalViewController = nil;
}

- (CGFloat)infobarModalContentHeight {
// TODO(crbug.com/911864): Implement, this is a temporary value. If
// InfobarConfirmCoordinator ends up having no Modal this should DCHECK or
// NOTREACHED.
return 50;
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#import "ios/chrome/browser/ui/infobars/infobar_badge_ui_delegate.h"
#import "ios/chrome/browser/ui/infobars/presentation/infobar_banner_positioner.h"
#import "ios/chrome/browser/ui/infobars/presentation/infobar_banner_transition_driver.h"
#import "ios/chrome/browser/ui/infobars/presentation/infobar_modal_positioner.h"
#import "ios/chrome/browser/ui/infobars/presentation/infobar_modal_transition_driver.h"
#import "ios/chrome/browser/ui/util/named_guide.h"

Expand All @@ -23,7 +24,8 @@
} // namespace

@interface InfobarCoordinator () <InfobarCoordinatorImplementation,
InfobarBannerPositioner> {
InfobarBannerPositioner,
InfobarModalPositioner> {
// The AnimatedFullscreenDisable disables fullscreen by displaying the
// Toolbar/s when an Infobar banner is presented.
std::unique_ptr<AnimatedScopedFullscreenDisabler> animatedFullscreenDisabler_;
Expand Down Expand Up @@ -97,6 +99,7 @@ - (void)presentInfobarModal {
DCHECK(self.baseViewController);
self.modalTransitionDriver = [[InfobarModalTransitionDriver alloc]
initWithTransitionMode:InfobarModalTransitionBase];
self.modalTransitionDriver.modalPositioner = self;
[self presentInfobarModalFrom:self.baseViewController
driver:self.modalTransitionDriver];
};
Expand Down Expand Up @@ -145,6 +148,7 @@ - (void)presentInfobarModalFromBanner {
DCHECK(self.bannerViewController);
self.modalTransitionDriver = [[InfobarModalTransitionDriver alloc]
initWithTransitionMode:InfobarModalTransitionBanner];
self.modalTransitionDriver.modalPositioner = self;
[self presentInfobarModalFrom:self.bannerViewController
driver:self.modalTransitionDriver];
}
Expand Down Expand Up @@ -216,6 +220,12 @@ - (void)dismissInfobarModal:(id)sender
}
}

#pragma mark InfobarModalPositioner

- (CGFloat)modalHeight {
return [self infobarModalContentHeight];
}

#pragma mark InfobarCoordinatorImplementation

- (void)configureModalViewController {
Expand All @@ -234,6 +244,11 @@ - (void)infobarWasDismissed {
NOTREACHED() << "Subclass must implement.";
}

- (CGFloat)infobarModalContentHeight {
NOTREACHED() << "Subclass must implement.";
return 0;
}

#pragma mark - Private

- (void)presentInfobarModalFrom:(UIViewController*)presentingViewController
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
// Transitioning from Banner to Modal won't call this method.
- (void)infobarWasDismissed;

// The infobar modal content height. Used to calculate its container height.
- (CGFloat)infobarModalContentHeight;

@end

#endif // IOS_CHROME_BROWSER_UI_INFOBARS_COORDINATORS_INFOBAR_COORDINATOR_IMPLEMENTATION_H_
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,13 @@ - (void)infobarWasDismissed {
self.modalViewController = nil;
}

- (CGFloat)infobarModalContentHeight {
UITableView* tableView = self.modalViewController.tableView;
[tableView setNeedsLayout];
[tableView layoutIfNeeded];
return tableView.contentSize.height;
}

#pragma mark - InfobarPasswordModalDelegate

- (void)updateCredentialsWithUsername:(NSString*)username
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ - (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
self.styler.cellBackgroundColor = [UIColor whiteColor];
self.tableView.scrollEnabled = NO;
self.tableView.sectionHeaderHeight = 0;
[self.tableView
setSeparatorInset:UIEdgeInsetsMake(0, kTableViewHorizontalSpacing, 0, 0)];
Expand All @@ -75,6 +74,12 @@ - (void)viewDidLoad {
[self loadModel];
}

- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
self.tableView.scrollEnabled =
self.tableView.contentSize.height > self.view.frame.size.height;
}

#pragma mark - TableViewModel

- (void)loadModel {
Expand Down
1 change: 1 addition & 0 deletions ios/chrome/browser/ui/infobars/presentation/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ source_set("presentation") {
"infobar_banner_transition_driver.mm",
"infobar_expand_banner_animator.h",
"infobar_expand_banner_animator.mm",
"infobar_modal_positioner.h",
"infobar_modal_presentation_controller.h",
"infobar_modal_presentation_controller.mm",
"infobar_modal_transition_driver.h",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright 2019 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_INFOBARS_PRESENTATION_INFOBAR_MODAL_POSITIONER_H_
#define IOS_CHROME_BROWSER_UI_INFOBARS_PRESENTATION_INFOBAR_MODAL_POSITIONER_H_

#import <UIKit/UIKit.h>

// InfobarBannerPositioner contains methods used to position the InfobarBanner.
@protocol InfobarModalPositioner

// The target height for the modal view to be presented.
- (CGFloat)modalHeight;

@end

#endif // IOS_CHROME_BROWSER_UI_INFOBARS_PRESENTATION_INFOBAR_MODAL_POSITIONER_H_
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,14 @@

#import <UIKit/UIKit.h>

@protocol InfobarModalPositioner;

// PresentationController for the ModalInfobar.
@interface InfobarModalPresentationController : UIPresentationController

// Delegate used to position the ModalInfobar.
@property(nonatomic, assign) id<InfobarModalPositioner> modalPositioner;

@end

#endif // IOS_CHROME_BROWSER_UI_INFOBARS_PRESENTATION_INFOBAR_MODAL_PRESENTATION_CONTROLLER_H_
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,27 @@

#import "ios/chrome/browser/ui/infobars/presentation/infobar_modal_presentation_controller.h"

#include "base/logging.h"
#import "ios/chrome/browser/ui/infobars/presentation/infobar_modal_positioner.h"
#import "ios/chrome/browser/ui/util/uikit_ui_util.h"

#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif

namespace {
// The presented view Height
const CGFloat kPresentedViewHeight = 350.0;
// The presented view outer horizontal margins.
const CGFloat kPresentedViewHorizontalMargin = 10.0;
const CGFloat kPresentedViewMargin = 10.0;
// The presented view maximum width.
const CGFloat kPresentedViewMaxWidth = 394.0;
// The rounded corner radius for the container view.
const CGFloat kContainerCornerRadius = 13.0;
// The background colot for the container view.
// The background color for the container view.
const int kContainerBackgroundColor = 0x2F2F2F;
// The alpha component for the container view background color.
const CGFloat kContainerBackgroundColorAlpha = 0.5;
// The modal view content vertical padding.
const CGFloat kModalViewVerticalPadding = 20;
} // namespace

@implementation InfobarModalPresentationController
Expand All @@ -40,21 +42,26 @@ - (void)containerViewWillLayoutSubviews {
}

- (CGRect)frameForPresentedView {
DCHECK(self.modalPositioner);
CGFloat containerWidth = CGRectGetWidth(self.containerView.bounds);
CGFloat containerHeight = CGRectGetHeight(self.containerView.bounds);

// Calculate the frame width.
CGFloat maxAvailableWidth =
containerWidth - 2 * kPresentedViewHorizontalMargin;
CGFloat maxAvailableWidth = containerWidth - 2 * kPresentedViewMargin;
CGFloat frameWidth = fmin(maxAvailableWidth, kPresentedViewMaxWidth);

// Calculate the frame height needed to fit the content.
CGFloat contentHeight = [self.modalPositioner modalHeight];
CGFloat maxAvailableHeight = containerHeight - 2 * kPresentedViewMargin;
CGFloat frameHeight =
fmin(maxAvailableHeight, contentHeight + kModalViewVerticalPadding);

// Based on the container width calculate the values in order to center the
// frame in the X and Y axis.
CGFloat modalXPosition = (containerWidth / 2) - (frameWidth / 2);
CGFloat modalYPosition = (containerHeight / 2) - (kPresentedViewHeight / 2);
CGFloat modalYPosition = (containerHeight / 2) - (frameHeight / 2);

return CGRectMake(modalXPosition, modalYPosition, frameWidth,
kPresentedViewHeight);
return CGRectMake(modalXPosition, modalYPosition, frameWidth, frameHeight);
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

#import <UIKit/UIKit.h>

@protocol InfobarModalPositioner;

typedef NS_ENUM(NSInteger, InfobarModalTransition) {
// InfobarModal will be presented from a base ViewController.
InfobarModalTransitionBase,
Expand All @@ -25,6 +27,9 @@ typedef NS_ENUM(NSInteger, InfobarModalTransition) {
// The InfobarModalTransition mode being used for this Transition driver.
@property(nonatomic, assign, readonly) InfobarModalTransition transitionMode;

// Delegate used to position the ModalInfobar.
@property(nonatomic, assign) id<InfobarModalPositioner> modalPositioner;

@end

#endif // IOS_CHROME_BROWSER_UI_INFOBARS_PRESENTATION_INFOBAR_MODAL_TRANSITION_DRIVER_H_
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ - (instancetype)initWithTransitionMode:(InfobarModalTransition)transitionMode {
[[InfobarModalPresentationController alloc]
initWithPresentedViewController:presented
presentingViewController:presenting];
presentationController.modalPositioner = self.modalPositioner;
return presentationController;
}

Expand Down
12 changes: 11 additions & 1 deletion ios/showcase/infobars/sc_infobar_banner_coordinator.mm
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#import "ios/chrome/browser/ui/infobars/modals/infobar_modal_view_controller.h"
#import "ios/chrome/browser/ui/infobars/presentation/infobar_banner_positioner.h"
#import "ios/chrome/browser/ui/infobars/presentation/infobar_banner_transition_driver.h"
#import "ios/chrome/browser/ui/infobars/presentation/infobar_modal_positioner.h"
#import "ios/chrome/browser/ui/infobars/presentation/infobar_modal_transition_driver.h"

#if !defined(__has_feature) || !__has_feature(objc_arc)
Expand All @@ -23,7 +24,8 @@

#pragma mark - ContainerViewController

@interface ContainerViewController : UIViewController <InfobarBannerPositioner>
@interface ContainerViewController
: UIViewController <InfobarBannerPositioner, InfobarModalPositioner>
@property(nonatomic, strong) InfobarBannerViewController* bannerViewController;
@property(nonatomic, strong)
InfobarBannerTransitionDriver* bannerTransitionDriver;
Expand Down Expand Up @@ -51,6 +53,13 @@ - (CGFloat)bannerYPosition {
- (UIView*)bannerView {
return self.bannerViewController.view;
}

#pragma mark InfobarBannerPositioner

- (CGFloat)modalHeight {
return 200;
}

@end

#pragma mark - SCInfobarBannerCoordinator
Expand Down Expand Up @@ -97,6 +106,7 @@ - (void)bannerInfobarButtonWasPressed:(id)sender {
- (void)presentInfobarModalFromBanner {
self.modalTransitionDriver = [[InfobarModalTransitionDriver alloc]
initWithTransitionMode:InfobarModalTransitionBanner];
self.modalTransitionDriver.modalPositioner = self.containerViewController;
self.modalViewController =
[[InfobarModalViewController alloc] initWithModalDelegate:self];
self.modalViewController.title = kInfobarBannerPresentedModalLabel;
Expand Down

0 comments on commit 945f121

Please sign in to comment.