Commit f5378dc0 authored by Gauthier Ambard's avatar Gauthier Ambard Committed by Commit Bot

[iOS] Add option selection for ConsentBump

This CL adds a way for the user to select an option in the ConsentBump
personalization screen.

Bug: 866506
Cq-Include-Trybots: luci.chromium.try:ios-simulator-full-configs;master.tryserver.chromium.mac:ios-simulator-cronet
Change-Id: Ia4da17b939a6ada46e8a8e6418a1c11e846014ed
Reviewed-on: https://chromium-review.googlesource.com/1160842
Commit-Queue: Gauthier Ambard <gambard@chromium.org>
Reviewed-by: default avatarJérôme Lebel <jlebel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#580479}
parent d757d321
...@@ -32,6 +32,7 @@ source_set("consent_bump_ui") { ...@@ -32,6 +32,7 @@ source_set("consent_bump_ui") {
"consent_bump_view_controller_delegate.h", "consent_bump_view_controller_delegate.h",
] ]
deps = [ deps = [
"resources:consent_bump_checkmark",
"//base", "//base",
"//ios/chrome/app/strings", "//ios/chrome/app/strings",
"//ios/chrome/browser/ui:ui_util", "//ios/chrome/browser/ui:ui_util",
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#import "ios/chrome/browser/ui/authentication/consent_bump/consent_bump_option_button.h" #import "ios/chrome/browser/ui/authentication/consent_bump/consent_bump_option_button.h"
#import "ios/chrome/browser/ui/authentication/authentication_constants.h" #import "ios/chrome/browser/ui/authentication/authentication_constants.h"
#include "ios/chrome/browser/ui/uikit_ui_util.h"
#import "ios/chrome/common/ui_util/constraints_ui_util.h" #import "ios/chrome/common/ui_util/constraints_ui_util.h"
#if !defined(__has_feature) || !__has_feature(objc_arc) #if !defined(__has_feature) || !__has_feature(objc_arc)
...@@ -16,6 +17,13 @@ const CGFloat kVerticalMargin = 8; ...@@ -16,6 +17,13 @@ const CGFloat kVerticalMargin = 8;
const CGFloat kTitleTextMargin = 4; const CGFloat kTitleTextMargin = 4;
const CGFloat kImageViewMargin = 16; const CGFloat kImageViewMargin = 16;
const CGFloat kCheckmarkSize = 18;
const int kCheckmarkColor = 0x1A73E8;
const CGFloat kHighlightAlpha = 0.07;
const CGFloat kAnimationDuration = 0.15;
} // namespace } // namespace
@interface ConsentBumpOptionButton () @interface ConsentBumpOptionButton ()
...@@ -23,6 +31,8 @@ const CGFloat kImageViewMargin = 16; ...@@ -23,6 +31,8 @@ const CGFloat kImageViewMargin = 16;
// Image view containing the check mark is the option is selected. // Image view containing the check mark is the option is selected.
@property(nonatomic, strong) UIImageView* checkMarkImageView; @property(nonatomic, strong) UIImageView* checkMarkImageView;
// Whether the highlight animation is running.
@property(nonatomic, assign) BOOL highlightAnimationRunning;
@end @end
@implementation ConsentBumpOptionButton @implementation ConsentBumpOptionButton
...@@ -30,6 +40,7 @@ const CGFloat kImageViewMargin = 16; ...@@ -30,6 +40,7 @@ const CGFloat kImageViewMargin = 16;
@synthesize checked = _checked; @synthesize checked = _checked;
@synthesize type = _type; @synthesize type = _type;
@synthesize checkMarkImageView = _checkMarkImageView; @synthesize checkMarkImageView = _checkMarkImageView;
@synthesize highlightAnimationRunning = _highlightAnimationRunning;
+ (instancetype)consentBumpOptionButtonWithTitle:(NSString*)title + (instancetype)consentBumpOptionButtonWithTitle:(NSString*)title
text:(NSString*)text { text:(NSString*)text {
...@@ -50,9 +61,14 @@ const CGFloat kImageViewMargin = 16; ...@@ -50,9 +61,14 @@ const CGFloat kImageViewMargin = 16;
separator.translatesAutoresizingMaskIntoConstraints = NO; separator.translatesAutoresizingMaskIntoConstraints = NO;
[option addSubview:separator]; [option addSubview:separator];
UIImageView* checkMarkImageView = [[UIImageView alloc] init]; UIImageView* checkMarkImageView = [[UIImageView alloc]
initWithImage:
[[UIImage imageNamed:@"consent_bump_checkmark"]
imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]];
option.checkMarkImageView = checkMarkImageView; option.checkMarkImageView = checkMarkImageView;
checkMarkImageView.translatesAutoresizingMaskIntoConstraints = NO; checkMarkImageView.translatesAutoresizingMaskIntoConstraints = NO;
checkMarkImageView.hidden = YES;
checkMarkImageView.tintColor = UIColorFromRGB(kCheckmarkColor);
[option addSubview:checkMarkImageView]; [option addSubview:checkMarkImageView];
id<LayoutGuideProvider> safeArea = SafeAreaLayoutGuideForView(option); id<LayoutGuideProvider> safeArea = SafeAreaLayoutGuideForView(option);
...@@ -111,6 +127,8 @@ const CGFloat kImageViewMargin = 16; ...@@ -111,6 +127,8 @@ const CGFloat kImageViewMargin = 16;
[checkMarkImageView.bottomAnchor [checkMarkImageView.bottomAnchor
constraintLessThanOrEqualToAnchor:option.bottomAnchor constraintLessThanOrEqualToAnchor:option.bottomAnchor
constant:-kImageViewMargin], constant:-kImageViewMargin],
[checkMarkImageView.heightAnchor constraintEqualToConstant:kCheckmarkSize],
[checkMarkImageView.widthAnchor constraintEqualToConstant:kCheckmarkSize],
// Separator. // Separator.
[separator.heightAnchor [separator.heightAnchor
...@@ -125,12 +143,65 @@ const CGFloat kImageViewMargin = 16; ...@@ -125,12 +143,65 @@ const CGFloat kImageViewMargin = 16;
return option; return option;
} }
#pragma mark - Properties
- (void)setChecked:(BOOL)checked { - (void)setChecked:(BOOL)checked {
if (checked == _checked) if (checked == _checked)
return; return;
_checked = checked; _checked = checked;
// TODO(crbug.com/866506): Update image. self.checkMarkImageView.hidden = !checked;
}
#pragma mark - UIButton
- (void)setHighlighted:(BOOL)highlighted {
[super setHighlighted:highlighted];
if (self.highlightAnimationRunning)
return;
if (highlighted) {
[self animateHighlighting];
} else {
[self animateUnhighlighting];
}
}
#pragma mark - Private
// Highlights this view, in an animated way. If at the end of the animation the
// view isn't |highlighted| anymore, the effect is removed.
- (void)animateHighlighting {
self.highlightAnimationRunning = YES;
[UIView animateWithDuration:kAnimationDuration
delay:0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
self.backgroundColor = [UIColor colorWithWhite:0 alpha:kHighlightAlpha];
}
completion:^(BOOL finished) {
self.highlightAnimationRunning = NO;
if (!self.highlighted)
[self animateUnhighlighting];
}];
}
// Unhighlights this view, in an animated way. If at the end of the animation
// the view is |highlighted|, the effect is added back.
- (void)animateUnhighlighting {
self.highlightAnimationRunning = YES;
[UIView animateWithDuration:kAnimationDuration
delay:0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
self.backgroundColor = [UIColor clearColor];
}
completion:^(BOOL finished) {
self.highlightAnimationRunning = NO;
if (self.highlighted)
[self animateHighlighting];
}];
} }
@end @end
...@@ -5,11 +5,15 @@ ...@@ -5,11 +5,15 @@
#ifndef IOS_CHROME_BROWSER_UI_AUTHENTICATION_CONSENT_BUMP_CONSENT_BUMP_PERSONALIZATION_COORDINATOR_H_ #ifndef IOS_CHROME_BROWSER_UI_AUTHENTICATION_CONSENT_BUMP_CONSENT_BUMP_PERSONALIZATION_COORDINATOR_H_
#define IOS_CHROME_BROWSER_UI_AUTHENTICATION_CONSENT_BUMP_CONSENT_BUMP_PERSONALIZATION_COORDINATOR_H_ #define IOS_CHROME_BROWSER_UI_AUTHENTICATION_CONSENT_BUMP_CONSENT_BUMP_PERSONALIZATION_COORDINATOR_H_
#import "ios/chrome/browser/ui/authentication/consent_bump/consent_bump_option_button.h"
#import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h" #import "ios/chrome/browser/ui/coordinators/chrome_coordinator.h"
// Coordinator for handling the ConsentBump Personalization screen. // Coordinator for handling the ConsentBump Personalization screen.
@interface ConsentBumpPersonalizationCoordinator : ChromeCoordinator @interface ConsentBumpPersonalizationCoordinator : ChromeCoordinator
// Type of the selected option.
@property(nonatomic, assign, readonly) ConsentBumpOptionType selectedOption;
// The view Controller for this coordinator. // The view Controller for this coordinator.
@property(nonatomic, strong, readonly) UIViewController* viewController; @property(nonatomic, strong, readonly) UIViewController* viewController;
......
...@@ -28,6 +28,10 @@ ...@@ -28,6 +28,10 @@
return self.personalizationViewController; return self.personalizationViewController;
} }
- (ConsentBumpOptionType)selectedOption {
return self.personalizationViewController.selectedOption;
}
#pragma mark - ChromeCoordinator #pragma mark - ChromeCoordinator
- (void)start { - (void)start {
......
...@@ -7,9 +7,14 @@ ...@@ -7,9 +7,14 @@
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#import "ios/chrome/browser/ui/authentication/consent_bump/consent_bump_option_button.h"
// View controller displaying the Personalization screen. // View controller displaying the Personalization screen.
@interface ConsentBumpPersonalizationViewController : UIViewController @interface ConsentBumpPersonalizationViewController : UIViewController
// The currently selected option.
@property(nonatomic, assign, readonly) ConsentBumpOptionType selectedOption;
@end @end
#endif // IOS_CHROME_BROWSER_UI_AUTHENTICATION_CONSENT_BUMP_CONSENT_BUMP_PERSONALIZATION_VIEW_CONTROLLER_H_ #endif // IOS_CHROME_BROWSER_UI_AUTHENTICATION_CONSENT_BUMP_CONSENT_BUMP_PERSONALIZATION_VIEW_CONTROLLER_H_
...@@ -29,6 +29,11 @@ const CGFloat kOptionsVerticalMargin = 16; ...@@ -29,6 +29,11 @@ const CGFloat kOptionsVerticalMargin = 16;
@property(nonatomic, strong) @property(nonatomic, strong)
NSLayoutConstraint* imageBackgroundViewHeightConstraint; NSLayoutConstraint* imageBackgroundViewHeightConstraint;
// Array containing all the options presented by this ViewController.
@property(nonatomic, copy) NSArray<ConsentBumpOptionButton*>* options;
// Redefined as readwrite.
@property(nonatomic, assign, readwrite) ConsentBumpOptionType selectedOption;
@end @end
@implementation ConsentBumpPersonalizationViewController @implementation ConsentBumpPersonalizationViewController
...@@ -36,6 +41,8 @@ const CGFloat kOptionsVerticalMargin = 16; ...@@ -36,6 +41,8 @@ const CGFloat kOptionsVerticalMargin = 16;
@synthesize scrollView = _scrollView; @synthesize scrollView = _scrollView;
@synthesize imageBackgroundViewHeightConstraint = @synthesize imageBackgroundViewHeightConstraint =
_imageBackgroundViewHeightConstraint; _imageBackgroundViewHeightConstraint;
@synthesize options = _options;
@synthesize selectedOption = _selectedOption;
- (void)viewDidLoad { - (void)viewDidLoad {
[super viewDidLoad]; [super viewDidLoad];
...@@ -103,6 +110,7 @@ const CGFloat kOptionsVerticalMargin = 16; ...@@ -103,6 +110,7 @@ const CGFloat kOptionsVerticalMargin = 16;
IDS_IOS_CONSENT_BUMP_NO_CHANGE_TEXT)]; IDS_IOS_CONSENT_BUMP_NO_CHANGE_TEXT)];
noChangeOption.type = ConsentBumpOptionTypeNoChange; noChangeOption.type = ConsentBumpOptionTypeNoChange;
noChangeOption.checked = YES; noChangeOption.checked = YES;
self.selectedOption = ConsentBumpOptionTypeNoChange;
ConsentBumpOptionButton* reviewOption = [ConsentBumpOptionButton ConsentBumpOptionButton* reviewOption = [ConsentBumpOptionButton
consentBumpOptionButtonWithTitle:l10n_util::GetNSString( consentBumpOptionButtonWithTitle:l10n_util::GetNSString(
...@@ -119,7 +127,7 @@ const CGFloat kOptionsVerticalMargin = 16; ...@@ -119,7 +127,7 @@ const CGFloat kOptionsVerticalMargin = 16;
turnOnOption.type = ConsentBumpOptionTypeTurnOn; turnOnOption.type = ConsentBumpOptionTypeTurnOn;
turnOnOption.checked = NO; turnOnOption.checked = NO;
NSArray<UIView*>* options = @[ noChangeOption, reviewOption, turnOnOption ]; self.options = @[ noChangeOption, reviewOption, turnOnOption ];
id<LayoutGuideProvider> safeArea = SafeAreaLayoutGuideForView(self.view); id<LayoutGuideProvider> safeArea = SafeAreaLayoutGuideForView(self.view);
AddSameConstraints(self.view, self.scrollView); AddSameConstraints(self.view, self.scrollView);
...@@ -155,10 +163,12 @@ const CGFloat kOptionsVerticalMargin = 16; ...@@ -155,10 +163,12 @@ const CGFloat kOptionsVerticalMargin = 16;
// Options positioning. // Options positioning.
UIView* viewAbove = nil; UIView* viewAbove = nil;
for (UIView* option in options) { for (ConsentBumpOptionButton* option in self.options) {
option.translatesAutoresizingMaskIntoConstraints = NO; option.translatesAutoresizingMaskIntoConstraints = NO;
[container addSubview:option]; [container addSubview:option];
// TODO(crbug.com/866506): Add action for the option. [option addTarget:self
action:@selector(optionTapped:)
forControlEvents:UIControlEventTouchUpInside];
if (viewAbove) { if (viewAbove) {
[option.topAnchor constraintEqualToAnchor:viewAbove.bottomAnchor].active = [option.topAnchor constraintEqualToAnchor:viewAbove.bottomAnchor].active =
...@@ -173,10 +183,11 @@ const CGFloat kOptionsVerticalMargin = 16; ...@@ -173,10 +183,11 @@ const CGFloat kOptionsVerticalMargin = 16;
// Positioning the first and last options. // Positioning the first and last options.
[NSLayoutConstraint activateConstraints:@[ [NSLayoutConstraint activateConstraints:@[
[options[0].topAnchor constraintEqualToAnchor:text.bottomAnchor [self.options[0].topAnchor constraintEqualToAnchor:text.bottomAnchor
constant:kOptionsVerticalMargin], constant:kOptionsVerticalMargin],
[container.bottomAnchor [container.bottomAnchor
constraintEqualToAnchor:options[options.count - 1].bottomAnchor constraintEqualToAnchor:self.options[self.options.count - 1]
.bottomAnchor
constant:kOptionsVerticalMargin], constant:kOptionsVerticalMargin],
]]; ]];
...@@ -204,6 +215,14 @@ const CGFloat kOptionsVerticalMargin = 16; ...@@ -204,6 +215,14 @@ const CGFloat kOptionsVerticalMargin = 16;
#pragma mark - Private #pragma mark - Private
- (void)optionTapped:(ConsentBumpOptionButton*)tappedOption {
for (ConsentBumpOptionButton* option in self.options) {
option.checked = NO;
}
tappedOption.checked = YES;
self.selectedOption = tappedOption.type;
}
// Updates constraints and content insets for the |scrollView| and // Updates constraints and content insets for the |scrollView| and
// |imageBackgroundView| related to non-safe area. // |imageBackgroundView| related to non-safe area.
- (void)updateScrollViewAndImageBackgroundView { - (void)updateScrollViewAndImageBackgroundView {
......
# Copyright 2017 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.
import("//build/config/ios/asset_catalog.gni")
imageset("consent_bump_checkmark") {
sources = [
"consent_bump_checkmark.imageset/Contents.json",
"consent_bump_checkmark.imageset/consent_bump_checkmark.png",
"consent_bump_checkmark.imageset/consent_bump_checkmark@2x.png",
"consent_bump_checkmark.imageset/consent_bump_checkmark@3x.png",
]
}
{
"images": [
{
"idiom": "universal",
"scale": "1x",
"filename": "consent_bump_checkmark.png"
},
{
"idiom": "universal",
"scale": "2x",
"filename": "consent_bump_checkmark@2x.png"
},
{
"idiom": "universal",
"scale": "3x",
"filename": "consent_bump_checkmark@3x.png"
}
],
"info": {
"version": 1,
"author": "xcode"
}
}
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