Commit 49f7b5a7 authored by sczs's avatar sczs Committed by Commit Bot

[ios] Decouples InfobarContainerView from InfobarContainerIOS

- InfobarCoordinator now owns the InfobarContainerView.
- Creates a consumer protocol to communicate between InfobarContainerIOS and InfobarContainerView.
 Paving the way for a mediator.
- Deletes cr_transitionWithView in favor of the stock method since InfobarContainerView
 was the last class using it

Bug: 892376
Cq-Include-Trybots: luci.chromium.try:ios-simulator-cronet;luci.chromium.try:ios-simulator-full-configs
Change-Id: I5ed216e48096bf59ec485460dc42dab250177e01
Reviewed-on: https://chromium-review.googlesource.com/c/1287315
Commit-Queue: Sergio Collazos <sczs@chromium.org>
Reviewed-by: default avatarMark Cogan <marq@chromium.org>
Cr-Commit-Position: refs/heads/master@{#600935}
parent 6673c997
......@@ -15,8 +15,6 @@ source_set("infobars") {
"infobar_container_ios.h",
"infobar_container_ios.mm",
"infobar_container_state_delegate.h",
"infobar_container_view.h",
"infobar_container_view.mm",
"infobar_controller+protected.h",
"infobar_controller.h",
"infobar_controller.mm",
......@@ -30,7 +28,6 @@ source_set("infobars") {
"//base",
"//components/translate/core/browser",
"//ios/chrome/browser/ui/infobars:infobars_ui",
"//ios/chrome/common",
"//ios/web",
"//ui/base",
"//ui/gfx",
......
......@@ -11,25 +11,16 @@
#include "base/macros.h"
@class InfoBarContainerView;
@protocol InfobarContainerConsumer;
// IOS infobar container specialization, managing infobars visibility so
// that only the front most one is visible at any time.
class InfoBarContainerIOS : public infobars::InfoBarContainer {
public:
explicit InfoBarContainerIOS(infobars::InfoBarContainer::Delegate* delegate);
InfoBarContainerIOS(infobars::InfoBarContainer::Delegate* delegate,
id<InfobarContainerConsumer> consumer);
~InfoBarContainerIOS() override;
// Returns the UIView container.
InfoBarContainerView* view();
// Hides the current infobar keeping the current state. If a new infobar is
// added, it will be hidden as well.
void SuspendInfobars();
// Restores the normal behavior of the infobars.
void RestoreInfobars();
protected:
void PlatformSpecificAddInfoBar(infobars::InfoBar* infobar,
size_t position) override;
......@@ -37,8 +28,8 @@ class InfoBarContainerIOS : public infobars::InfoBarContainer {
void PlatformSpecificInfoBarStateChanged(bool is_animating) override;
private:
InfoBarContainerView* container_view_;
InfoBarContainer::Delegate* delegate_;
id<InfobarContainerConsumer> consumer_;
DISALLOW_COPY_AND_ASSIGN(InfoBarContainerIOS);
};
......
......@@ -5,45 +5,20 @@
#include "ios/chrome/browser/infobars/infobar_container_ios.h"
#include <stddef.h>
#import <UIKit/UIKit.h>
#include "base/logging.h"
#include "ios/chrome/browser/infobars/infobar.h"
#include "ios/chrome/browser/infobars/infobar_container_view.h"
#import "ios/chrome/common/material_timing.h"
#import "ios/chrome/browser/ui/infobars/infobar_container_consumer.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
void SetViewAlphaWithAnimation(UIView* view, float alpha) {
CGFloat oldAlpha = [view alpha];
if (oldAlpha > 0 && alpha == 0) {
[view setUserInteractionEnabled:NO];
}
[UIView cr_transitionWithView:view
duration:ios::material::kDuration3
curve:ios::material::CurveEaseInOut
options:0
animations:^{
[view setAlpha:alpha];
}
completion:^(BOOL) {
if (oldAlpha == 0 && alpha > 0) {
[view setUserInteractionEnabled:YES];
};
}];
}
} // namespace
InfoBarContainerIOS::InfoBarContainerIOS(
infobars::InfoBarContainer::Delegate* delegate)
: InfoBarContainer(delegate), delegate_(delegate) {
infobars::InfoBarContainer::Delegate* delegate,
id<InfobarContainerConsumer> consumer)
: InfoBarContainer(delegate), delegate_(delegate), consumer_(consumer) {
DCHECK(delegate);
container_view_ = [[InfoBarContainerView alloc] init];
[container_view_ setAutoresizingMask:UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleTopMargin];
}
InfoBarContainerIOS::~InfoBarContainerIOS() {
......@@ -51,14 +26,10 @@ InfoBarContainerIOS::~InfoBarContainerIOS() {
RemoveAllInfoBarsForDestruction();
}
InfoBarContainerView* InfoBarContainerIOS::view() {
return container_view_;
}
void InfoBarContainerIOS::PlatformSpecificAddInfoBar(infobars::InfoBar* infobar,
size_t position) {
InfoBarIOS* infobar_ios = static_cast<InfoBarIOS*>(infobar);
[container_view_ addInfoBar:infobar_ios position:position];
[consumer_ addInfoBar:infobar_ios position:position];
}
void InfoBarContainerIOS::PlatformSpecificRemoveInfoBar(
......@@ -76,14 +47,6 @@ void InfoBarContainerIOS::PlatformSpecificRemoveInfoBar(
void InfoBarContainerIOS::PlatformSpecificInfoBarStateChanged(
bool is_animating) {
[container_view_ setUserInteractionEnabled:!is_animating];
[container_view_ setNeedsLayout];
}
void InfoBarContainerIOS::SuspendInfobars() {
SetViewAlphaWithAnimation(container_view_, 0);
}
void InfoBarContainerIOS::RestoreInfobars() {
SetViewAlphaWithAnimation(container_view_, 1);
[consumer_ setUserInteractionEnabled:!is_animating];
[consumer_ updateLayout];
}
// Copyright 2012 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_INFOBARS_INFOBAR_CONTAINER_VIEW_H_
#define IOS_CHROME_BROWSER_INFOBARS_INFOBAR_CONTAINER_VIEW_H_
#import <UIKit/UIKit.h>
class InfoBarIOS;
@interface InfoBarContainerView : UIView {
}
// Add a new infobar to the container view at position |position|.
- (void)addInfoBar:(InfoBarIOS*)infoBarIOS position:(NSInteger)position;
// Height of the frontmost infobar that is not hidden.
- (CGFloat)topmostVisibleInfoBarHeight;
@end
#endif // IOS_CHROME_BROWSER_INFOBARS_INFOBAR_CONTAINER_VIEW_H_
......@@ -5,10 +5,14 @@
source_set("infobars") {
configs += [ "//build/config/compiler:enable_arc" ]
sources = [
# TODO(crbug.com/892376): Move infobar_container_view to infobars_ui.
"infobar_container_view.h",
"infobar_container_view.mm",
"infobar_coordinator.h",
"infobar_coordinator.mm",
]
deps = [
":infobars_ui",
":public",
"//base",
"//ios/chrome/browser/infobars",
......@@ -21,6 +25,7 @@ source_set("infobars") {
"//ios/chrome/browser/upgrade",
"//ios/chrome/browser/web:tab_id_tab_helper",
"//ios/chrome/browser/web_state_list",
"//ui/base",
]
}
......@@ -37,6 +42,7 @@ source_set("infobars_ui") {
"confirm_infobar_view.mm",
"infobar_constants.h",
"infobar_constants.mm",
"infobar_container_consumer.h",
"infobar_view_sizing.h",
"infobar_view_sizing_delegate.h",
]
......
// 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_INFOBARS_INFOBAR_CONTAINER_CONSUMER_H_
#define IOS_CHROME_BROWSER_UI_INFOBARS_INFOBAR_CONTAINER_CONSUMER_H_
#import <UIKit/UIKit.h>
class InfoBarIOS;
// Protocol to communicate with the Infobar container.
@protocol InfobarContainerConsumer
// Add a new infobar to the Infobar container view at position |position|.
- (void)addInfoBar:(InfoBarIOS*)infoBarIOS position:(NSInteger)position;
// Height of the frontmost infobar contained in Infobar container that is not
// hidden.
- (CGFloat)topmostVisibleInfoBarHeight;
// Animates the Infobar container alpha to |alpha|.
- (void)animateInfoBarContainerToAlpha:(CGFloat)alpha;
// Sets the Infobar container user interaction to |enabled|.
- (void)setUserInteractionEnabled:(BOOL)enabled;
// Updates Infobar container layout. This should be called when Infobar
// container needs to re-draw.
- (void)updateLayout;
@end
#endif // IOS_CHROME_BROWSER_UI_INFOBARS_INFOBAR_CONTAINER_CONSUMER_H_
// Copyright 2012 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_INFOBAR_CONTAINER_VIEW_H_
#define IOS_CHROME_BROWSER_UI_INFOBARS_INFOBAR_CONTAINER_VIEW_H_
#import <UIKit/UIKit.h>
#import "ios/chrome/browser/ui/infobars/infobar_container_consumer.h"
@interface InfoBarContainerView : UIView<InfobarContainerConsumer>
@end
#endif // IOS_CHROME_BROWSER_UI_INFOBARS_INFOBAR_CONTAINER_VIEW_H_
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/infobars/infobar_container_view.h"
#import "ios/chrome/browser/ui/infobars/infobar_container_view.h"
#include "base/logging.h"
#include "ios/chrome/browser/infobars/infobar.h"
......@@ -12,8 +12,24 @@
#error "This file requires ARC support."
#endif
namespace {
// Duration for the alpha change animation.
const CGFloat kAlphaChangeAnimationDuration = 0.35;
} // namespace
@implementation InfoBarContainerView
- (void)layoutSubviews {
for (UIView<InfoBarViewSizing>* view in self.subviews) {
[view sizeToFit];
CGRect frame = view.frame;
frame.origin.y = CGRectGetHeight(frame) - [view visibleHeight];
[view setFrame:frame];
}
}
#pragma mark - InfobarConsumer
- (void)addInfoBar:(InfoBarIOS*)infoBarIOS position:(NSInteger)position {
DCHECK_LE((NSUInteger)position, [[self subviews] count]);
CGRect containerBounds = [self bounds];
......@@ -24,38 +40,34 @@
[self insertSubview:view atIndex:position];
}
- (CGSize)sizeThatFits:(CGSize)size {
CGFloat height = 0;
if (ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_TABLET) {
for (UIView* view in self.subviews) {
CGSize elementSize = [view sizeThatFits:size];
height += elementSize.height;
}
} else {
for (UIView* view in self.subviews) {
CGFloat elementHeight = [view sizeThatFits:size].height;
if (elementHeight > height)
height = elementHeight;
}
- (CGFloat)topmostVisibleInfoBarHeight {
for (UIView* view in [self.subviews reverseObjectEnumerator]) {
return [view sizeThatFits:self.frame.size].height;
}
size.height = height;
return size;
return 0;
}
- (void)layoutSubviews {
for (UIView<InfoBarViewSizing>* view in self.subviews) {
[view sizeToFit];
CGRect frame = view.frame;
frame.origin.y = CGRectGetHeight(frame) - [view visibleHeight];
[view setFrame:frame];
- (void)animateInfoBarContainerToAlpha:(CGFloat)alpha {
CGFloat oldAlpha = self.alpha;
if (oldAlpha > 0 && alpha == 0) {
[self setUserInteractionEnabled:NO];
}
[UIView transitionWithView:self
duration:kAlphaChangeAnimationDuration
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
[self setAlpha:alpha];
}
completion:^(BOOL) {
if (oldAlpha == 0 && alpha > 0) {
[self setUserInteractionEnabled:YES];
};
}];
}
- (CGFloat)topmostVisibleInfoBarHeight {
for (UIView* view in [self.subviews reverseObjectEnumerator]) {
return [view sizeThatFits:self.frame.size].height;
}
return 0;
- (void)updateLayout {
[self setNeedsLayout];
}
@end
......@@ -9,13 +9,13 @@
#include "base/ios/block_types.h"
#include "ios/chrome/browser/infobars/infobar_container_delegate_ios.h"
#include "ios/chrome/browser/infobars/infobar_container_ios.h"
#include "ios/chrome/browser/infobars/infobar_container_view.h"
#include "ios/chrome/browser/infobars/infobar_manager_impl.h"
#import "ios/chrome/browser/tabs/tab.h"
#import "ios/chrome/browser/tabs/tab_model.h"
#import "ios/chrome/browser/tabs/tab_model_observer.h"
#import "ios/chrome/browser/ui/authentication/re_signin_infobar_delegate.h"
#import "ios/chrome/browser/ui/commands/application_commands.h"
#include "ios/chrome/browser/ui/infobars/infobar_container_view.h"
#import "ios/chrome/browser/ui/infobars/infobar_positioner.h"
#import "ios/chrome/browser/ui/settings/sync_utils/sync_util.h"
#import "ios/chrome/browser/ui/signin_interaction/public/signin_presenter.h"
......@@ -41,6 +41,9 @@
}
@property(nonatomic, assign) TabModel* tabModel;
// UIView that contains Infobars.
@property(nonatomic, strong) InfoBarContainerView* containerView;
@end
@implementation InfobarCoordinator
......@@ -54,20 +57,23 @@
if (self) {
_tabModel = tabModel;
[_tabModel addObserver:self];
_containerView = [[InfoBarContainerView alloc] init];
[_containerView setAutoresizingMask:UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleTopMargin];
_infoBarContainerDelegate.reset(new InfoBarContainerDelegateIOS(self));
_infoBarContainer.reset(
new InfoBarContainerIOS(_infoBarContainerDelegate.get()));
_infoBarContainer.reset(new InfoBarContainerIOS(
_infoBarContainerDelegate.get(), _containerView));
}
return self;
}
- (void)start {
[self.baseViewController.view insertSubview:_infoBarContainer->view()
[self.baseViewController.view insertSubview:self.containerView
aboveSubview:self.positioner.parentView];
CGRect infoBarFrame = self.positioner.parentView.frame;
infoBarFrame.origin.y = CGRectGetMaxY(infoBarFrame);
infoBarFrame.size.height = 0;
[_infoBarContainer->view() setFrame:infoBarFrame];
[self.containerView setFrame:infoBarFrame];
infobars::InfoBarManager* infoBarManager = nullptr;
if (self.tabModel.currentTab) {
......@@ -89,15 +95,15 @@
#pragma mark - Public Interface
- (UIView*)view {
return _infoBarContainer->view();
return self.containerView;
}
- (void)restoreInfobars {
_infoBarContainer->RestoreInfobars();
[self.containerView animateInfoBarContainerToAlpha:1];
}
- (void)suspendInfobars {
_infoBarContainer->SuspendInfobars();
[self.containerView animateInfoBarContainerToAlpha:0];
}
......@@ -117,7 +123,7 @@
#pragma mark - InfobarContainerStateDelegate
- (void)infoBarContainerStateDidChangeAnimated:(BOOL)animated {
InfoBarContainerView* infoBarContainerView = _infoBarContainer->view();
InfoBarContainerView* infoBarContainerView = self.containerView;
DCHECK(infoBarContainerView);
CGRect containerFrame = infoBarContainerView.frame;
CGFloat height = [infoBarContainerView topmostVisibleInfoBarHeight];
......
......@@ -52,19 +52,6 @@ CAMediaTimingFunction* TimingFunction(Curve curve);
animations:(void (^)(void))animations
completion:(void (^)(BOOL finished))completion;
// Performs a standard UIView transition animation using a material timing
// |curve|.
// Note: any curve option specified in |options| will be ignored in favor of the
// specified curve value.
// See also:
// +[UIView transitionWithView:duration:options:animations:completion].
+ (void)cr_transitionWithView:(UIView*)view
duration:(NSTimeInterval)duration
curve:(ios::material::Curve)curve
options:(UIViewAnimationOptions)options
animations:(void (^)(void))animations
completion:(void (^)(BOOL finished))completion;
@end
#endif // IOS_CHROME_COMMON_MATERIAL_TIMING_H_
......@@ -100,20 +100,4 @@ CAMediaTimingFunction* TimingFunction(Curve curve) {
[CATransaction commit];
}
+ (void)cr_transitionWithView:(UIView*)view
duration:(NSTimeInterval)duration
curve:(ios::material::Curve)curve
options:(UIViewAnimationOptions)options
animations:(void (^)(void))animations
completion:(void (^)(BOOL finished))completion {
[CATransaction begin];
[CATransaction setAnimationTimingFunction:TimingFunction(curve)];
[UIView transitionWithView:view
duration:duration
options:AnimationOptionsForceLinearTiming(options)
animations:animations
completion:completion];
[CATransaction commit];
}
@end
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