[ios] Presents InfobarModal when Banner is tapped.
The Banner is animated to scale down and then back to its original size
before presenting the Modal.
TBR=sczs@chromium.org
(cherry picked from commit c4450e5ac680ff1ff2200df2b611d607bcc2147e)
Bug: 911864, 973168
Change-Id: Iac6f4435b39f188d7f24e2576b7ca429bcbccf0b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1648534
Commit-Queue: Sergio Collazos <sczs@chromium.org>
Reviewed-by: Chris Lu <thegreenfrog@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#668150}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1656188
Reviewed-by: Sergio Collazos <sczs@chromium.org>
Cr-Commit-Position: refs/branch-heads/3809@{#257}
Cr-Branched-From: d82dec1a818f378c464ba307ddd9c92133eac355-refs/heads/master@{#665002}
diff --git a/ios/chrome/browser/infobars/infobar_metrics_recorder.h b/ios/chrome/browser/infobars/infobar_metrics_recorder.h
index cdaa336..3cc19fc 100644
--- a/ios/chrome/browser/infobars/infobar_metrics_recorder.h
+++ b/ios/chrome/browser/infobars/infobar_metrics_recorder.h
@@ -35,10 +35,12 @@
TimedOut = 0,
// Infobar Banner was dismissed by being swiped up.
SwipedUp = 1,
- // Infobar Banner was dismissed by being expanded into an Infobar Modal.
+ // Infobar Banner was dismissed by being dragged into an Infobar Modal.
ExpandedToModal = 2,
+ // Infobar Banner was dismissed by being tapped into an Infobar Modal.
+ TappedToModal = 3,
// Highest enumerator. Recommended by Histogram metrics best practices.
- kMaxValue = ExpandedToModal,
+ kMaxValue = TappedToModal,
};
// Values for the UMA Mobile.Messages.Modal.Event histogram. These values
diff --git a/ios/chrome/browser/ui/infobars/banners/infobar_banner_view_controller.mm b/ios/chrome/browser/ui/infobars/banners/infobar_banner_view_controller.mm
index 0cbbd5b1..3717dfd 100644
--- a/ios/chrome/browser/ui/infobars/banners/infobar_banner_view_controller.mm
+++ b/ios/chrome/browser/ui/infobars/banners/infobar_banner_view_controller.mm
@@ -23,8 +23,10 @@
const CGFloat kBannerViewShadowOpacity = 0.23;
// Banner View selected constants.
+const CGFloat kTappedBannerViewScale = 0.98;
const CGFloat kSelectedBannerViewScale = 1.02;
const CGFloat kSelectBannerAnimationDurationInSeconds = 0.2;
+const CGFloat kTappedBannerAnimationDurationInSeconds = 0.1;
const CGFloat kSelectedBannerViewYShadowOffset = 8.0;
// Bottom Grip constants.
@@ -226,6 +228,11 @@
longPressGestureRecognizer.minimumPressDuration =
kLongPressTimeDurationInSeconds;
[self.view addGestureRecognizer:longPressGestureRecognizer];
+
+ UITapGestureRecognizer* tapGestureRecognizer = [[UITapGestureRecognizer alloc]
+ initWithTarget:self
+ action:@selector(animateBannerTappedAndPresentModal)];
+ [self.view addGestureRecognizer:tapGestureRecognizer];
}
- (void)viewDidAppear:(BOOL)animated {
@@ -289,7 +296,9 @@
}
if (gesture.state == UIGestureRecognizerStateEnded) {
- [self animateBannerToOriginalState];
+ [self animateBannerToOriginalStateWithDuration:
+ kSelectBannerAnimationDurationInSeconds
+ completion:nil];
// If dragged up by more than kChangeInPositionForDismissal at the time
// the gesture ended, OR |self.shouldDismissAfterTouchesEnded| is YES.
// Dismiss the banner.
@@ -333,15 +342,18 @@
}
// Animate the Banner back to its original size and styling.
-- (void)animateBannerToOriginalState {
- [UIView
- animateWithDuration:kSelectBannerAnimationDurationInSeconds
- animations:^{
- self.view.superview.transform = CGAffineTransformIdentity;
- [self.view.layer
- setShadowOffset:CGSizeMake(0.0, kBannerViewYShadowOffset)];
- }
- completion:nil];
+- (void)animateBannerToOriginalStateWithDuration:(NSTimeInterval)duration
+ completion:(ProceduralBlock)completion {
+ [UIView animateWithDuration:duration
+ animations:^{
+ self.view.superview.transform = CGAffineTransformIdentity;
+ [self.view.layer
+ setShadowOffset:CGSizeMake(0.0, kBannerViewYShadowOffset)];
+ }
+ completion:^(BOOL finished) {
+ if (completion)
+ completion();
+ }];
}
// Animate the banner back to its original position.
@@ -353,6 +365,32 @@
completion:nil];
}
+// Animate the Banner being tapped by scaling it down and then to its original
+// state. After the animation it presentd the Infobar Modal.
+- (void)animateBannerTappedAndPresentModal {
+ [UIView animateWithDuration:kTappedBannerAnimationDurationInSeconds
+ animations:^{
+ self.view.superview.transform = CGAffineTransformMakeScale(
+ kTappedBannerViewScale, kTappedBannerViewScale);
+ [self.view.layer
+ setShadowOffset:CGSizeMake(0.0, kSelectedBannerViewYShadowOffset)];
+ }
+ completion:^(BOOL finished) {
+ [self
+ animateBannerToOriginalStateWithDuration:
+ kTappedBannerAnimationDurationInSeconds
+ completion:^{
+ [self presentInfobarModalAfterTap];
+ }];
+ }];
+}
+
+- (void)presentInfobarModalAfterTap {
+ [self.metricsRecorder
+ recordBannerDismissType:MobileMessagesBannerDismissType::TappedToModal];
+ [self.delegate presentInfobarModalFromBanner];
+}
+
#pragma mark - Accessibility
- (NSArray*)accessibilityActions {
@@ -369,14 +407,14 @@
target:self
selector:@selector(dismiss)];
- UIAccessibilityCustomAction* expandAction =
+ UIAccessibilityCustomAction* modalAction =
[[UIAccessibilityCustomAction alloc]
initWithName:l10n_util::GetNSString(
IDS_IOS_INFOBAR_BANNER_OPTIONS_HINT)
target:self
- selector:@selector(presentInfobarModal)];
+ selector:@selector(triggerInfobarModal)];
- return @[ acceptAction, dismissAction, expandAction ];
+ return @[ acceptAction, dismissAction, modalAction ];
}
// A11y Custom actions selectors need to return a BOOL.
@@ -384,12 +422,12 @@
[self bannerInfobarButtonWasPressed:nil];
return NO;
}
-- (BOOL)presentInfobarModal {
- [self.metricsRecorder
- recordBannerDismissType:MobileMessagesBannerDismissType::ExpandedToModal];
- [self.delegate presentInfobarModalFromBanner];
+
+- (BOOL)triggerInfobarModal {
+ [self presentInfobarModalAfterTap];
return NO;
}
+
- (BOOL)dismiss {
[self.delegate dismissInfobarBanner:self animated:YES completion:nil];
return NO;
diff --git a/ios/showcase/infobars/sc_infobar_banner_coordinator_egtest.mm b/ios/showcase/infobars/sc_infobar_banner_coordinator_egtest.mm
index 7699eac..3f04a7f 100644
--- a/ios/showcase/infobars/sc_infobar_banner_coordinator_egtest.mm
+++ b/ios/showcase/infobars/sc_infobar_banner_coordinator_egtest.mm
@@ -116,4 +116,31 @@
assertWithMatcher:grey_nil()];
}
+// Tests that the InfobarModal is presented when the Banner its tapped.
+- (void)testInfobarBannerTapped {
+ // Check Banner was presented.
+ [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
+ kInfobarBannerViewIdentifier)]
+ assertWithMatcher:grey_notNil()];
+ // Tap Banner.
+ [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
+ kInfobarBannerViewIdentifier)]
+ performAction:grey_tap()];
+ // Check Modal was presented.
+ [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
+ kInfobarBannerPresentedModalLabel)]
+ assertWithMatcher:grey_notNil()];
+ // Dismiss Modal.
+ [[EarlGrey
+ selectElementWithMatcher:grey_accessibilityID(kInfobarModalCancelButton)]
+ performAction:grey_tap()];
+ // Check neither the Banner nor Modal are presented.
+ [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
+ kInfobarBannerViewIdentifier)]
+ assertWithMatcher:grey_nil()];
+ [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
+ kInfobarBannerPresentedModalLabel)]
+ assertWithMatcher:grey_nil()];
+}
+
@end
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index d37fc22..5d3709dc 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -38680,6 +38680,7 @@
<int value="0" label="TimedOut"/>
<int value="1" label="SwipedUp"/>
<int value="2" label="ExpandedToModal"/>
+ <int value="3" label="TappedToModal"/>
</enum>
<enum name="MobileMessagesBannerEvent">