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") { ...@@ -15,8 +15,6 @@ source_set("infobars") {
"infobar_container_ios.h", "infobar_container_ios.h",
"infobar_container_ios.mm", "infobar_container_ios.mm",
"infobar_container_state_delegate.h", "infobar_container_state_delegate.h",
"infobar_container_view.h",
"infobar_container_view.mm",
"infobar_controller+protected.h", "infobar_controller+protected.h",
"infobar_controller.h", "infobar_controller.h",
"infobar_controller.mm", "infobar_controller.mm",
...@@ -30,7 +28,6 @@ source_set("infobars") { ...@@ -30,7 +28,6 @@ source_set("infobars") {
"//base", "//base",
"//components/translate/core/browser", "//components/translate/core/browser",
"//ios/chrome/browser/ui/infobars:infobars_ui", "//ios/chrome/browser/ui/infobars:infobars_ui",
"//ios/chrome/common",
"//ios/web", "//ios/web",
"//ui/base", "//ui/base",
"//ui/gfx", "//ui/gfx",
......
...@@ -11,25 +11,16 @@ ...@@ -11,25 +11,16 @@
#include "base/macros.h" #include "base/macros.h"
@class InfoBarContainerView; @protocol InfobarContainerConsumer;
// IOS infobar container specialization, managing infobars visibility so // IOS infobar container specialization, managing infobars visibility so
// that only the front most one is visible at any time. // that only the front most one is visible at any time.
class InfoBarContainerIOS : public infobars::InfoBarContainer { class InfoBarContainerIOS : public infobars::InfoBarContainer {
public: public:
explicit InfoBarContainerIOS(infobars::InfoBarContainer::Delegate* delegate); InfoBarContainerIOS(infobars::InfoBarContainer::Delegate* delegate,
id<InfobarContainerConsumer> consumer);
~InfoBarContainerIOS() override; ~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: protected:
void PlatformSpecificAddInfoBar(infobars::InfoBar* infobar, void PlatformSpecificAddInfoBar(infobars::InfoBar* infobar,
size_t position) override; size_t position) override;
...@@ -37,8 +28,8 @@ class InfoBarContainerIOS : public infobars::InfoBarContainer { ...@@ -37,8 +28,8 @@ class InfoBarContainerIOS : public infobars::InfoBarContainer {
void PlatformSpecificInfoBarStateChanged(bool is_animating) override; void PlatformSpecificInfoBarStateChanged(bool is_animating) override;
private: private:
InfoBarContainerView* container_view_;
InfoBarContainer::Delegate* delegate_; InfoBarContainer::Delegate* delegate_;
id<InfobarContainerConsumer> consumer_;
DISALLOW_COPY_AND_ASSIGN(InfoBarContainerIOS); DISALLOW_COPY_AND_ASSIGN(InfoBarContainerIOS);
}; };
......
...@@ -5,45 +5,20 @@ ...@@ -5,45 +5,20 @@
#include "ios/chrome/browser/infobars/infobar_container_ios.h" #include "ios/chrome/browser/infobars/infobar_container_ios.h"
#include <stddef.h> #include <stddef.h>
#import <UIKit/UIKit.h>
#include "base/logging.h" #include "base/logging.h"
#include "ios/chrome/browser/infobars/infobar.h" #include "ios/chrome/browser/infobars/infobar.h"
#include "ios/chrome/browser/infobars/infobar_container_view.h" #import "ios/chrome/browser/ui/infobars/infobar_container_consumer.h"
#import "ios/chrome/common/material_timing.h"
#if !defined(__has_feature) || !__has_feature(objc_arc) #if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support." #error "This file requires ARC support."
#endif #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( InfoBarContainerIOS::InfoBarContainerIOS(
infobars::InfoBarContainer::Delegate* delegate) infobars::InfoBarContainer::Delegate* delegate,
: InfoBarContainer(delegate), delegate_(delegate) { id<InfobarContainerConsumer> consumer)
: InfoBarContainer(delegate), delegate_(delegate), consumer_(consumer) {
DCHECK(delegate); DCHECK(delegate);
container_view_ = [[InfoBarContainerView alloc] init];
[container_view_ setAutoresizingMask:UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleTopMargin];
} }
InfoBarContainerIOS::~InfoBarContainerIOS() { InfoBarContainerIOS::~InfoBarContainerIOS() {
...@@ -51,14 +26,10 @@ InfoBarContainerIOS::~InfoBarContainerIOS() { ...@@ -51,14 +26,10 @@ InfoBarContainerIOS::~InfoBarContainerIOS() {
RemoveAllInfoBarsForDestruction(); RemoveAllInfoBarsForDestruction();
} }
InfoBarContainerView* InfoBarContainerIOS::view() {
return container_view_;
}
void InfoBarContainerIOS::PlatformSpecificAddInfoBar(infobars::InfoBar* infobar, void InfoBarContainerIOS::PlatformSpecificAddInfoBar(infobars::InfoBar* infobar,
size_t position) { size_t position) {
InfoBarIOS* infobar_ios = static_cast<InfoBarIOS*>(infobar); InfoBarIOS* infobar_ios = static_cast<InfoBarIOS*>(infobar);
[container_view_ addInfoBar:infobar_ios position:position]; [consumer_ addInfoBar:infobar_ios position:position];
} }
void InfoBarContainerIOS::PlatformSpecificRemoveInfoBar( void InfoBarContainerIOS::PlatformSpecificRemoveInfoBar(
...@@ -76,14 +47,6 @@ void InfoBarContainerIOS::PlatformSpecificRemoveInfoBar( ...@@ -76,14 +47,6 @@ void InfoBarContainerIOS::PlatformSpecificRemoveInfoBar(
void InfoBarContainerIOS::PlatformSpecificInfoBarStateChanged( void InfoBarContainerIOS::PlatformSpecificInfoBarStateChanged(
bool is_animating) { bool is_animating) {
[container_view_ setUserInteractionEnabled:!is_animating]; [consumer_ setUserInteractionEnabled:!is_animating];
[container_view_ setNeedsLayout]; [consumer_ updateLayout];
}
void InfoBarContainerIOS::SuspendInfobars() {
SetViewAlphaWithAnimation(container_view_, 0);
}
void InfoBarContainerIOS::RestoreInfobars() {
SetViewAlphaWithAnimation(container_view_, 1);
} }
// 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 @@ ...@@ -5,10 +5,14 @@
source_set("infobars") { source_set("infobars") {
configs += [ "//build/config/compiler:enable_arc" ] configs += [ "//build/config/compiler:enable_arc" ]
sources = [ 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.h",
"infobar_coordinator.mm", "infobar_coordinator.mm",
] ]
deps = [ deps = [
":infobars_ui",
":public", ":public",
"//base", "//base",
"//ios/chrome/browser/infobars", "//ios/chrome/browser/infobars",
...@@ -21,6 +25,7 @@ source_set("infobars") { ...@@ -21,6 +25,7 @@ source_set("infobars") {
"//ios/chrome/browser/upgrade", "//ios/chrome/browser/upgrade",
"//ios/chrome/browser/web:tab_id_tab_helper", "//ios/chrome/browser/web:tab_id_tab_helper",
"//ios/chrome/browser/web_state_list", "//ios/chrome/browser/web_state_list",
"//ui/base",
] ]
} }
...@@ -37,6 +42,7 @@ source_set("infobars_ui") { ...@@ -37,6 +42,7 @@ source_set("infobars_ui") {
"confirm_infobar_view.mm", "confirm_infobar_view.mm",
"infobar_constants.h", "infobar_constants.h",
"infobar_constants.mm", "infobar_constants.mm",
"infobar_container_consumer.h",
"infobar_view_sizing.h", "infobar_view_sizing.h",
"infobar_view_sizing_delegate.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 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // 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 "base/logging.h"
#include "ios/chrome/browser/infobars/infobar.h" #include "ios/chrome/browser/infobars/infobar.h"
...@@ -12,8 +12,24 @@ ...@@ -12,8 +12,24 @@
#error "This file requires ARC support." #error "This file requires ARC support."
#endif #endif
namespace {
// Duration for the alpha change animation.
const CGFloat kAlphaChangeAnimationDuration = 0.35;
} // namespace
@implementation InfoBarContainerView @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 { - (void)addInfoBar:(InfoBarIOS*)infoBarIOS position:(NSInteger)position {
DCHECK_LE((NSUInteger)position, [[self subviews] count]); DCHECK_LE((NSUInteger)position, [[self subviews] count]);
CGRect containerBounds = [self bounds]; CGRect containerBounds = [self bounds];
...@@ -24,38 +40,34 @@ ...@@ -24,38 +40,34 @@
[self insertSubview:view atIndex:position]; [self insertSubview:view atIndex:position];
} }
- (CGSize)sizeThatFits:(CGSize)size { - (CGFloat)topmostVisibleInfoBarHeight {
CGFloat height = 0; for (UIView* view in [self.subviews reverseObjectEnumerator]) {
if (ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_TABLET) { return [view sizeThatFits:self.frame.size].height;
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;
}
} }
size.height = height; return 0;
return size;
} }
- (void)layoutSubviews { - (void)animateInfoBarContainerToAlpha:(CGFloat)alpha {
for (UIView<InfoBarViewSizing>* view in self.subviews) { CGFloat oldAlpha = self.alpha;
[view sizeToFit]; if (oldAlpha > 0 && alpha == 0) {
CGRect frame = view.frame; [self setUserInteractionEnabled:NO];
frame.origin.y = CGRectGetHeight(frame) - [view visibleHeight];
[view setFrame:frame];
} }
[UIView transitionWithView:self
duration:kAlphaChangeAnimationDuration
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
[self setAlpha:alpha];
}
completion:^(BOOL) {
if (oldAlpha == 0 && alpha > 0) {
[self setUserInteractionEnabled:YES];
};
}];
} }
- (CGFloat)topmostVisibleInfoBarHeight { - (void)updateLayout {
for (UIView* view in [self.subviews reverseObjectEnumerator]) { [self setNeedsLayout];
return [view sizeThatFits:self.frame.size].height;
}
return 0;
} }
@end @end
...@@ -9,13 +9,13 @@ ...@@ -9,13 +9,13 @@
#include "base/ios/block_types.h" #include "base/ios/block_types.h"
#include "ios/chrome/browser/infobars/infobar_container_delegate_ios.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_ios.h"
#include "ios/chrome/browser/infobars/infobar_container_view.h"
#include "ios/chrome/browser/infobars/infobar_manager_impl.h" #include "ios/chrome/browser/infobars/infobar_manager_impl.h"
#import "ios/chrome/browser/tabs/tab.h" #import "ios/chrome/browser/tabs/tab.h"
#import "ios/chrome/browser/tabs/tab_model.h" #import "ios/chrome/browser/tabs/tab_model.h"
#import "ios/chrome/browser/tabs/tab_model_observer.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/authentication/re_signin_infobar_delegate.h"
#import "ios/chrome/browser/ui/commands/application_commands.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/infobars/infobar_positioner.h"
#import "ios/chrome/browser/ui/settings/sync_utils/sync_util.h" #import "ios/chrome/browser/ui/settings/sync_utils/sync_util.h"
#import "ios/chrome/browser/ui/signin_interaction/public/signin_presenter.h" #import "ios/chrome/browser/ui/signin_interaction/public/signin_presenter.h"
...@@ -41,6 +41,9 @@ ...@@ -41,6 +41,9 @@
} }
@property(nonatomic, assign) TabModel* tabModel; @property(nonatomic, assign) TabModel* tabModel;
// UIView that contains Infobars.
@property(nonatomic, strong) InfoBarContainerView* containerView;
@end @end
@implementation InfobarCoordinator @implementation InfobarCoordinator
...@@ -54,20 +57,23 @@ ...@@ -54,20 +57,23 @@
if (self) { if (self) {
_tabModel = tabModel; _tabModel = tabModel;
[_tabModel addObserver:self]; [_tabModel addObserver:self];
_containerView = [[InfoBarContainerView alloc] init];
[_containerView setAutoresizingMask:UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleTopMargin];
_infoBarContainerDelegate.reset(new InfoBarContainerDelegateIOS(self)); _infoBarContainerDelegate.reset(new InfoBarContainerDelegateIOS(self));
_infoBarContainer.reset( _infoBarContainer.reset(new InfoBarContainerIOS(
new InfoBarContainerIOS(_infoBarContainerDelegate.get())); _infoBarContainerDelegate.get(), _containerView));
} }
return self; return self;
} }
- (void)start { - (void)start {
[self.baseViewController.view insertSubview:_infoBarContainer->view() [self.baseViewController.view insertSubview:self.containerView
aboveSubview:self.positioner.parentView]; aboveSubview:self.positioner.parentView];
CGRect infoBarFrame = self.positioner.parentView.frame; CGRect infoBarFrame = self.positioner.parentView.frame;
infoBarFrame.origin.y = CGRectGetMaxY(infoBarFrame); infoBarFrame.origin.y = CGRectGetMaxY(infoBarFrame);
infoBarFrame.size.height = 0; infoBarFrame.size.height = 0;
[_infoBarContainer->view() setFrame:infoBarFrame]; [self.containerView setFrame:infoBarFrame];
infobars::InfoBarManager* infoBarManager = nullptr; infobars::InfoBarManager* infoBarManager = nullptr;
if (self.tabModel.currentTab) { if (self.tabModel.currentTab) {
...@@ -89,15 +95,15 @@ ...@@ -89,15 +95,15 @@
#pragma mark - Public Interface #pragma mark - Public Interface
- (UIView*)view { - (UIView*)view {
return _infoBarContainer->view(); return self.containerView;
} }
- (void)restoreInfobars { - (void)restoreInfobars {
_infoBarContainer->RestoreInfobars(); [self.containerView animateInfoBarContainerToAlpha:1];
} }
- (void)suspendInfobars { - (void)suspendInfobars {
_infoBarContainer->SuspendInfobars(); [self.containerView animateInfoBarContainerToAlpha:0];
} }
...@@ -117,7 +123,7 @@ ...@@ -117,7 +123,7 @@
#pragma mark - InfobarContainerStateDelegate #pragma mark - InfobarContainerStateDelegate
- (void)infoBarContainerStateDidChangeAnimated:(BOOL)animated { - (void)infoBarContainerStateDidChangeAnimated:(BOOL)animated {
InfoBarContainerView* infoBarContainerView = _infoBarContainer->view(); InfoBarContainerView* infoBarContainerView = self.containerView;
DCHECK(infoBarContainerView); DCHECK(infoBarContainerView);
CGRect containerFrame = infoBarContainerView.frame; CGRect containerFrame = infoBarContainerView.frame;
CGFloat height = [infoBarContainerView topmostVisibleInfoBarHeight]; CGFloat height = [infoBarContainerView topmostVisibleInfoBarHeight];
......
...@@ -52,19 +52,6 @@ CAMediaTimingFunction* TimingFunction(Curve curve); ...@@ -52,19 +52,6 @@ CAMediaTimingFunction* TimingFunction(Curve curve);
animations:(void (^)(void))animations animations:(void (^)(void))animations
completion:(void (^)(BOOL finished))completion; 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 @end
#endif // IOS_CHROME_COMMON_MATERIAL_TIMING_H_ #endif // IOS_CHROME_COMMON_MATERIAL_TIMING_H_
...@@ -100,20 +100,4 @@ CAMediaTimingFunction* TimingFunction(Curve curve) { ...@@ -100,20 +100,4 @@ CAMediaTimingFunction* TimingFunction(Curve curve) {
[CATransaction commit]; [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 @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