Commit 07c70e29 authored by Jérôme Lebel's avatar Jérôme Lebel Committed by Commit Bot

[iOS] Adding identity picker view

This patch adds a simple view that will be used to redo the sign-in workflow
for unity project.
This patch implements the IdentityPickerView which is the grey button with the
down arrow. This can be seen in the mock[1] for the sign-in workflow.

The accessibility is not done yet. The rest of the dialog will be implemented
soon.

IdentityPickerView:
https://drive.google.com/open?id=1bHM8QGHl7uTVMcUMLm-v3WRclj4kNyEc
IdentityPickerView in situe:
https://drive.google.com/open?id=1P3ZkJqNnk9ShIUwdaSbX-aZjvPn7NReg
IdentityPickerView with email only:
https://drive.google.com/open?id=18jD8IZlngQbKa_KkZ6ZADsxDdRl32yn4
IdentityPickerView with big fonts:
https://drive.google.com/open?id=1OLiDdQC6Tl1qBiG7ciVliAqX0LAwTXxz
IdentityPickerView email only with big font:
https://drive.google.com/open?id=1JkVtbTWQyCLwxwUeu0x_0nTKPvhFD9rE


Mock[1]:
https://docs.google.com/presentation/d/1cZfr5FGWGSy0PNaQ8uzik0alLAH-5glh1vsb030vha8/edit?ts=5aba5455#slide=id.g353bc22139_3_19

Bug: 827072
Cq-Include-Trybots: master.tryserver.chromium.mac:ios-simulator-cronet;master.tryserver.chromium.mac:ios-simulator-full-configs
Change-Id: Ia3caddb069b951e734161901325206555d8af0ae
Reviewed-on: https://chromium-review.googlesource.com/995417
Commit-Queue: Jérôme Lebel <jlebel@chromium.org>
Reviewed-by: default avatarGauthier Ambard <gambard@chromium.org>
Cr-Commit-Position: refs/heads/master@{#548812}
parent 7ce5235a
......@@ -31,6 +31,7 @@ source_set("authentication") {
]
deps = [
":authentication_ui",
"resources:identity_picker_view_arrow_down",
"resources:signin_confirmation_more",
"resources:signin_promo_close_gray",
"//base",
......
// 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_AUTHENTICATION_IDENTITY_PICKER_VIEW_H_
#define IOS_CHROME_BROWSER_UI_AUTHENTICATION_IDENTITY_PICKER_VIEW_H_
#import <UIKit/UIKit.h>
// Displays the name, email and avatar of a chrome identity, as a control.
// An down arrow is also displayed on the right of the control, to invite the
// user to tap and select another chrome identity. To get the tap event, see:
// -[UIControl addTarget:action:forControlEvents:].
@interface IdentityPickerView : UIControl
// Initialises IdentityPickerView.
- (instancetype)initWithFrame:(CGRect)frame NS_DESIGNATED_INITIALIZER;
// See -[IdentityPickerView initWithFrame:].
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE;
// Set the identity avatar shown.
- (void)setIdentityAvatar:(UIImage*)identityAvatar;
// Set the name and email shown. |name| can be nil.
- (void)setIdentityName:(NSString*)name email:(NSString*)email;
@end
#endif // IOS_CHROME_BROWSER_UI_AUTHENTICATION_IDENTITY_PICKER_VIEW_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.
#import "ios/chrome/browser/ui/authentication/identity_picker_view.h"
#include "base/logging.h"
#import "ios/chrome/browser/ui/uikit_ui_util.h"
#import "ios/chrome/browser/ui/util/constraints_ui_util.h"
#import "ios/third_party/material_components_ios/src/components/Ink/src/MaterialInk.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
const CGFloat kIdentityPickerViewRadius = 8.;
// Sizes.
const CGFloat kIdentityAvatarSize = 40.;
const CGFloat kTitleFontSize = 14.;
const CGFloat kSubtitleFontSize = 12.;
const CGFloat kArrowDownSize = 24.;
// Distances/margins.
const CGFloat kTitleOffset = 2;
const CGFloat kArrowDownMargin = 12.;
const CGFloat kHorizontalAvatarMargin = 16.;
const CGFloat kVerticalMargin = 12.;
// Colors
const CGFloat kTitleTextColorAlpha = .87;
const CGFloat kSubtitleTextColorAlpha = .54;
} // namespace
@interface IdentityPickerView ()
@property(nonatomic) UIImageView* avatarImageView;
@property(nonatomic) UILabel* title;
@property(nonatomic) UILabel* subtitle;
@property(nonatomic) MDCInkView* inkView;
@property(nonatomic) NSLayoutConstraint* titleConstraintForNameAndEmail;
@property(nonatomic) NSLayoutConstraint* titleConstraintForEmailOnly;
@end
@implementation IdentityPickerView
@synthesize avatarImageView = _avatarImageView;
@synthesize title = _title;
@synthesize subtitle = _subtitle;
@synthesize inkView = _inkView;
// Constraints when email and name are available.
@synthesize titleConstraintForNameAndEmail = _titleConstraintForNameAndEmail;
// Constraints when only the email is avaiable.
@synthesize titleConstraintForEmailOnly = _titleConstraintForEmailOnly;
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.layer.cornerRadius = kIdentityPickerViewRadius;
self.backgroundColor = [UIColor colorWithRed:241. / 255.
green:243. / 255.
blue:244. / 255.
alpha:1.];
// Adding view elements inside.
// Ink view.
_inkView = [[MDCInkView alloc] initWithFrame:CGRectZero];
_inkView.layer.cornerRadius = kIdentityPickerViewRadius;
_inkView.inkStyle = MDCInkStyleBounded;
_inkView.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:_inkView];
// Avatar view.
_avatarImageView = [[UIImageView alloc] initWithFrame:CGRectZero];
_avatarImageView.translatesAutoresizingMaskIntoConstraints = NO;
[self addSubview:_avatarImageView];
// Arrow down.
UIImageView* arrowDownImageView =
[[UIImageView alloc] initWithFrame:CGRectZero];
arrowDownImageView.translatesAutoresizingMaskIntoConstraints = NO;
arrowDownImageView.image =
[UIImage imageNamed:@"identity_picker_view_arrow_down"];
[self addSubview:arrowDownImageView];
// Title.
_title = [[UILabel alloc] initWithFrame:CGRectZero];
_title.translatesAutoresizingMaskIntoConstraints = NO;
_title.textColor = [UIColor colorWithWhite:0 alpha:kTitleTextColorAlpha];
_title.font = [UIFont systemFontOfSize:kTitleFontSize];
[self addSubview:_title];
// Subtitle.
_subtitle = [[UILabel alloc] initWithFrame:CGRectZero];
_subtitle.translatesAutoresizingMaskIntoConstraints = NO;
_subtitle.textColor =
[UIColor colorWithWhite:0 alpha:kSubtitleTextColorAlpha];
_subtitle.font = [UIFont systemFontOfSize:kSubtitleFontSize];
[self addSubview:_subtitle];
// Layout constraints.
NSDictionary* views = @{
@"avatar" : _avatarImageView,
@"title" : _title,
@"subtitle" : _subtitle,
@"arrow" : arrowDownImageView,
};
NSDictionary* metrics = @{
@"ArMrg" : @(kArrowDownMargin),
@"ArrowSize" : @(kArrowDownSize),
@"AvatarSize" : @(kIdentityAvatarSize),
@"HAvatMrg" : @(kHorizontalAvatarMargin),
@"VMargin" : @(kVerticalMargin),
};
NSArray* constraints = @[
// Horizontal constraints.
@"H:|-(HAvatMrg)-[avatar]-(HAvatMrg)-[title]-(ArMrg)-[arrow]-(ArMrg)-|",
// Vertical constraints.
@"V:|-(>=VMargin)-[avatar]-(>=VMargin)-|",
@"V:|-(>=VMargin)-[title]",
@"V:[subtitle]-(>=VMargin)-|",
// Size constraints.
@"H:[avatar(AvatarSize)]",
@"V:[avatar(AvatarSize)]",
@"H:[arrow(ArrowSize)]",
@"V:[arrow(ArrowSize)]",
];
AddSameCenterYConstraint(self, _avatarImageView);
AddSameCenterYConstraint(self, arrowDownImageView);
ApplyVisualConstraintsWithMetrics(constraints, views, metrics);
AddSameConstraintsToSides(_title, _subtitle,
LayoutSides::kLeading | LayoutSides::kTrailing);
_titleConstraintForNameAndEmail =
[self.centerYAnchor constraintEqualToAnchor:_title.bottomAnchor
constant:kTitleOffset];
_titleConstraintForEmailOnly =
[self.centerYAnchor constraintEqualToAnchor:_title.centerYAnchor];
[self.centerYAnchor constraintEqualToAnchor:_subtitle.topAnchor
constant:-kTitleOffset]
.active = YES;
}
return self;
}
#pragma mark - Setter
- (void)setIdentityAvatar:(UIImage*)identityAvatar {
_avatarImageView.image =
CircularImageFromImage(identityAvatar, kIdentityAvatarSize);
}
- (void)setIdentityName:(NSString*)name email:(NSString*)email {
DCHECK(email);
if (!name || name.length == 0) {
self.titleConstraintForNameAndEmail.active = NO;
self.titleConstraintForEmailOnly.active = YES;
self.subtitle.hidden = YES;
self.title.text = email;
} else {
self.titleConstraintForEmailOnly.active = NO;
self.titleConstraintForNameAndEmail.active = YES;
self.subtitle.hidden = NO;
self.title.text = name;
self.subtitle.text = email;
}
}
#pragma mark - Private
- (CGPoint)locationFromTouches:(NSSet*)touches {
UITouch* touch = [touches anyObject];
return [touch locationInView:self];
}
#pragma mark - UIResponder
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
[super touchesBegan:touches withEvent:event];
CGPoint location = [self locationFromTouches:touches];
[self.inkView startTouchBeganAnimationAtPoint:location completion:nil];
}
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
[super touchesEnded:touches withEvent:event];
CGPoint location = [self locationFromTouches:touches];
[self.inkView startTouchEndedAnimationAtPoint:location completion:nil];
}
- (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event {
[super touchesCancelled:touches withEvent:event];
CGPoint location = [self locationFromTouches:touches];
[self.inkView startTouchEndedAnimationAtPoint:location completion:nil];
}
@end
......@@ -4,6 +4,14 @@
import("//build/config/ios/asset_catalog.gni")
imageset("identity_picker_view_arrow_down") {
sources = [
"identity_picker_view_arrow_down.imageset/Contents.json",
"identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down.png",
"identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down@2x.png",
"identity_picker_view_arrow_down.imageset/identity_picker_view_arrow_down@3x.png",
]
}
imageset("signin_confirmation_more") {
sources = [
"signin_confirmation_more.imageset/Contents.json",
......
{
"images": [
{
"idiom": "universal",
"scale": "1x",
"filename": "identity_picker_view_arrow_down.png"
},
{
"idiom": "universal",
"scale": "2x",
"filename": "identity_picker_view_arrow_down@2x.png"
},
{
"idiom": "universal",
"scale": "3x",
"filename": "identity_picker_view_arrow_down@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