Commit cf155c5c authored by Ewann's avatar Ewann Committed by Commit Bot

[iOS] Updates link label to texts view in welcome screen

based on: https://crrev.com/c/2300383
This CL updates the link label used to display the TOS string to an UITextView.
A sublcass is needed to override the |canBecomeFirstResponder| method.

On iOS 13,we can't override |canBecomeFirstResponder| or the whole
string will responds to a tap.

On iOS 12, the whole string responds to a tap if we use this current
implementation.

Bug: 1102996
Change-Id: Id9c9e3089d07a056c365043e1d60b1b558586ccf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2302900
Commit-Queue: Ewann Pellé <ewannpv@chromium.org>
Reviewed-by: default avatarSylvain Defresne <sdefresne@chromium.org>
Reviewed-by: default avatarGauthier Ambard <gambard@chromium.org>
Reviewed-by: default avatarJavier Ernesto Flores Robles <javierrobles@chromium.org>
Cr-Commit-Position: refs/heads/master@{#791755}
parent 2474fd40
...@@ -18,6 +18,8 @@ source_set("elements") { ...@@ -18,6 +18,8 @@ source_set("elements") {
"selector_view_controller_delegate.h", "selector_view_controller_delegate.h",
"text_field_configuration.h", "text_field_configuration.h",
"text_field_configuration.mm", "text_field_configuration.mm",
"text_view_selection_disabled.h",
"text_view_selection_disabled.mm",
"top_aligned_image_view.h", "top_aligned_image_view.h",
"top_aligned_image_view.mm", "top_aligned_image_view.mm",
"windowed_container_view.h", "windowed_container_view.h",
......
// Copyright 2020 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_ELEMENTS_TEXT_VIEW_SELECTION_DISABLED_H_
#define IOS_CHROME_BROWSER_UI_ELEMENTS_TEXT_VIEW_SELECTION_DISABLED_H_
#import <UIKit/UIKit.h>
// UITextView subclass is needed to override -canBecomeFirstResponder to prevent
// text selection while maintaining clickable link.
@interface TextViewSelectionDisabled : UITextView
@end
#endif // IOS_CHROME_BROWSER_UI_ELEMENTS_TEXT_VIEW_SELECTION_DISABLED_H_
// Copyright 2020 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/elements/text_view_selection_disabled.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@implementation TextViewSelectionDisabled
- (BOOL)canBecomeFirstResponder {
if (@available(iOS 14.0, *))
return NO;
// On iOS 13, the whole string responds to a tap if
// canBecomeFirstResponder returns NO.
return YES;
}
@end
...@@ -37,6 +37,7 @@ source_set("first_run") { ...@@ -37,6 +37,7 @@ source_set("first_run") {
"//ios/chrome/browser/ui/authentication", "//ios/chrome/browser/ui/authentication",
"//ios/chrome/browser/ui/authentication/signin", "//ios/chrome/browser/ui/authentication/signin",
"//ios/chrome/browser/ui/commands", "//ios/chrome/browser/ui/commands",
"//ios/chrome/browser/ui/elements",
"//ios/chrome/browser/ui/fancy_ui", "//ios/chrome/browser/ui/fancy_ui",
"//ios/chrome/browser/ui/icons", "//ios/chrome/browser/ui/icons",
"//ios/chrome/browser/ui/material_components", "//ios/chrome/browser/ui/material_components",
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "base/i18n/rtl.h" #include "base/i18n/rtl.h"
#include "base/notreached.h" #include "base/notreached.h"
#include "base/strings/sys_string_conversions.h" #include "base/strings/sys_string_conversions.h"
#import "ios/chrome/browser/ui/elements/text_view_selection_disabled.h"
#include "ios/chrome/browser/ui/fancy_ui/primary_action_button.h" #include "ios/chrome/browser/ui/fancy_ui/primary_action_button.h"
#include "ios/chrome/browser/ui/first_run/first_run_util.h" #include "ios/chrome/browser/ui/first_run/first_run_util.h"
#import "ios/chrome/browser/ui/util/CRUILabel+AttributeUtils.h" #import "ios/chrome/browser/ui/util/CRUILabel+AttributeUtils.h"
...@@ -63,7 +64,7 @@ const CGFloat kContainerViewCompactWidthPercentage = 0.8; ...@@ -63,7 +64,7 @@ const CGFloat kContainerViewCompactWidthPercentage = 0.8;
// Layout constants. // Layout constants.
const CGFloat kImageTopPadding[SIZE_CLASS_COUNT] = {32.0, 50.0}; const CGFloat kImageTopPadding[SIZE_CLASS_COUNT] = {32.0, 50.0};
const CGFloat kTOSLabelTopPadding[SIZE_CLASS_COUNT] = {34.0, 40.0}; const CGFloat kTOSTextViewTopPadding[SIZE_CLASS_COUNT] = {34.0, 40.0};
const CGFloat kOptInLabelPadding[SIZE_CLASS_COUNT] = {10.0, 14.0}; const CGFloat kOptInLabelPadding[SIZE_CLASS_COUNT] = {10.0, 14.0};
const CGFloat kCheckBoxPadding[SIZE_CLASS_COUNT] = {10.0, 16.0}; const CGFloat kCheckBoxPadding[SIZE_CLASS_COUNT] = {10.0, 16.0};
const CGFloat kOKButtonBottomPadding[SIZE_CLASS_COUNT] = {32.0, 32.0}; const CGFloat kOKButtonBottomPadding[SIZE_CLASS_COUNT] = {32.0, 32.0};
...@@ -73,8 +74,8 @@ const CGFloat kAppLogoProportionMultiplier = 0.381966; ...@@ -73,8 +74,8 @@ const CGFloat kAppLogoProportionMultiplier = 0.381966;
// Font sizes. // Font sizes.
const CGFloat kTitleLabelFontSize[SIZE_CLASS_COUNT] = {24.0, 36.0}; const CGFloat kTitleLabelFontSize[SIZE_CLASS_COUNT] = {24.0, 36.0};
const CGFloat kTOSLabelFontSize[SIZE_CLASS_COUNT] = {14.0, 21.0}; const CGFloat kTOSTOSTextViewFontSize[SIZE_CLASS_COUNT] = {14.0, 21.0};
const CGFloat kTOSLabelLineHeight[SIZE_CLASS_COUNT] = {20.0, 32.0}; const CGFloat kLegacyTOSLabelLineHeight[SIZE_CLASS_COUNT] = {20.0, 32.0};
const CGFloat kOptInLabelFontSize[SIZE_CLASS_COUNT] = {13.0, 19.0}; const CGFloat kOptInLabelFontSize[SIZE_CLASS_COUNT] = {13.0, 19.0};
const CGFloat kOptInLabelLineHeight[SIZE_CLASS_COUNT] = {18.0, 26.0}; const CGFloat kOptInLabelLineHeight[SIZE_CLASS_COUNT] = {18.0, 26.0};
const CGFloat kOKButtonTitleLabelFontSize[SIZE_CLASS_COUNT] = {14.0, 20.0}; const CGFloat kOKButtonTitleLabelFontSize[SIZE_CLASS_COUNT] = {14.0, 20.0};
...@@ -94,29 +95,35 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service"; ...@@ -94,29 +95,35 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service";
} // namespace } // namespace
@interface WelcomeToChromeView () { @interface WelcomeToChromeView () <UITextViewDelegate> {
UIView* _containerView; UIView* _containerView;
UILabel* _titleLabel; UILabel* _titleLabel;
UIImageView* _imageView; UIImageView* _imageView;
UILabel* _TOSLabel;
LabelLinkController* _TOSLabelLinkController;
UIButton* _checkBoxButton; UIButton* _checkBoxButton;
UILabel* _optInLabel; UILabel* _optInLabel;
PrimaryActionButton* _OKButton; PrimaryActionButton* _OKButton;
// Used for iOS 12 compatibility.
UILabel* _legacyTOSLabel;
LabelLinkController* _legacyTOSLabelLinkController;
} }
// Subview properties are lazily instantiated upon their first use. // Subview properties are lazily instantiated upon their first use.
// The "Terms of Service" legacy label used for iOS 12 compatibility.
@property(strong, nonatomic, readonly) UILabel* legacyTOSLabel;
// Legacy observer for setting the size of the TOSLabel with cr_lineHeight used
// for iOS 12 compatibility.
@property(strong, nonatomic) LabelObserver* legacyTOSObserver;
// A container view used to layout and center subviews. // A container view used to layout and center subviews.
@property(strong, nonatomic, readonly) UIView* containerView; @property(strong, nonatomic, readonly) UIView* containerView;
// The "Welcome to Chrome" label that appears at the top of the view. // The "Welcome to Chrome" label that appears at the top of the view.
@property(strong, nonatomic, readonly) UILabel* titleLabel; @property(strong, nonatomic, readonly) UILabel* titleLabel;
// The Chrome logo image view. // The Chrome logo image view.
@property(strong, nonatomic, readonly) UIImageView* imageView; @property(strong, nonatomic, readonly) UIImageView* imageView;
// The "Terms of Service" label. // The "Terms of Service" text view.
@property(strong, nonatomic, readonly) UILabel* TOSLabel; @property(strong, nonatomic) TextViewSelectionDisabled* TOSTextView;
// Observer for setting the size of the TOSLabel with cr_lineHeight.
@property(strong, nonatomic) LabelObserver* TOSObserver;
// The stats reporting opt-in label. // The stats reporting opt-in label.
@property(strong, nonatomic, readonly) UILabel* optInLabel; @property(strong, nonatomic, readonly) UILabel* optInLabel;
// Observer for setting the size of the optInLabel with cr_lineHeight. // Observer for setting the size of the optInLabel with cr_lineHeight.
...@@ -130,7 +137,7 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service"; ...@@ -130,7 +137,7 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service";
// subsequent subview layouts depend on the layouts that precede them. // subsequent subview layouts depend on the layouts that precede them.
- (void)layoutTitleLabel; - (void)layoutTitleLabel;
- (void)layoutImageView; - (void)layoutImageView;
- (void)layoutTOSLabel; - (void)layoutTOSTextView;
- (void)layoutOptInLabel; - (void)layoutOptInLabel;
- (void)layoutCheckBoxButton; - (void)layoutCheckBoxButton;
- (void)layoutContainerView; - (void)layoutContainerView;
...@@ -142,7 +149,7 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service"; ...@@ -142,7 +149,7 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service";
// Subview configuration methods. // Subview configuration methods.
- (void)configureTitleLabel; - (void)configureTitleLabel;
- (void)configureImageView; - (void)configureImageView;
- (void)configureTOSLabel; - (void)configureTOSTextView;
- (void)configureOptInLabel; - (void)configureOptInLabel;
- (void)configureContainerView; - (void)configureContainerView;
- (void)configureOKButton; - (void)configureOKButton;
...@@ -157,10 +164,6 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service"; ...@@ -157,10 +164,6 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service";
@implementation WelcomeToChromeView @implementation WelcomeToChromeView
@synthesize delegate = _delegate;
@synthesize TOSObserver = _TOSObserver;
@synthesize optInObserver = _optInObserver;
- (instancetype)initWithFrame:(CGRect)frame { - (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame]; self = [super initWithFrame:frame];
if (self) { if (self) {
...@@ -175,7 +178,8 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service"; ...@@ -175,7 +178,8 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service";
// Prepare for animation by making views (except for the logo) transparent // Prepare for animation by making views (except for the logo) transparent
// and finding the initial and final location of the logo. // and finding the initial and final location of the logo.
self.titleLabel.alpha = 0.0; self.titleLabel.alpha = 0.0;
self.TOSLabel.alpha = 0.0; self.TOSTextView.alpha = 0.0;
self.legacyTOSLabel.alpha = 0.0;
self.optInLabel.alpha = 0.0; self.optInLabel.alpha = 0.0;
self.checkBoxButton.alpha = 0.0; self.checkBoxButton.alpha = 0.0;
self.OKButton.alpha = 0.0; self.OKButton.alpha = 0.0;
...@@ -196,7 +200,8 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service"; ...@@ -196,7 +200,8 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service";
animations:^{ animations:^{
[weakSelf imageView].frame = finalLogoFrame; [weakSelf imageView].frame = finalLogoFrame;
[weakSelf titleLabel].alpha = 1.0; [weakSelf titleLabel].alpha = 1.0;
[weakSelf TOSLabel].alpha = 1.0; [weakSelf TOSTextView].alpha = 1.0;
[weakSelf legacyTOSLabel].alpha = 1.0;
[weakSelf optInLabel].alpha = 1.0; [weakSelf optInLabel].alpha = 1.0;
[weakSelf checkBoxButton].alpha = 1.0; [weakSelf checkBoxButton].alpha = 1.0;
[weakSelf OKButton].alpha = 1.0; [weakSelf OKButton].alpha = 1.0;
...@@ -205,7 +210,8 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service"; ...@@ -205,7 +210,8 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service";
} }
- (void)dealloc { - (void)dealloc {
[self.TOSObserver stopObserving]; [self.legacyTOSObserver stopObserving];
[self.optInObserver stopObserving]; [self.optInObserver stopObserving];
} }
...@@ -247,17 +253,24 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service"; ...@@ -247,17 +253,24 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service";
return _imageView; return _imageView;
} }
- (UILabel*)TOSLabel { - (TextViewSelectionDisabled*)TOSTextView {
if (!_TOSLabel) { if (!_TOSTextView) {
_TOSLabel = [[UILabel alloc] initWithFrame:CGRectZero]; _TOSTextView = [[TextViewSelectionDisabled alloc] initWithFrame:CGRectZero];
}
return _TOSTextView;
}
- (UILabel*)legacyTOSLabel {
if (!_legacyTOSLabel) {
_legacyTOSLabel = [[UILabel alloc] initWithFrame:CGRectZero];
// Add an observer to the label to be able to keep the cr_lineHeight. // Add an observer to the label to be able to keep the cr_lineHeight.
self.TOSObserver = [LabelObserver observerForLabel:_TOSLabel]; self.legacyTOSObserver = [LabelObserver observerForLabel:_legacyTOSLabel];
[self.TOSObserver startObserving]; [self.legacyTOSObserver startObserving];
[_TOSLabel setNumberOfLines:0]; [_legacyTOSLabel setNumberOfLines:0];
[_TOSLabel setTextAlignment:NSTextAlignmentCenter]; [_legacyTOSLabel setTextAlignment:NSTextAlignmentCenter];
} }
return _TOSLabel; return _legacyTOSLabel;
} }
- (UILabel*)optInLabel { - (UILabel*)optInLabel {
...@@ -328,7 +341,11 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service"; ...@@ -328,7 +341,11 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service";
[self addSubview:self.containerView]; [self addSubview:self.containerView];
[self.containerView addSubview:self.titleLabel]; [self.containerView addSubview:self.titleLabel];
[self.containerView addSubview:self.imageView]; [self.containerView addSubview:self.imageView];
[self.containerView addSubview:self.TOSLabel]; if (@available(iOS 13.0, *)) {
[self.containerView addSubview:self.TOSTextView];
} else {
[self.containerView addSubview:self.legacyTOSLabel];
}
[self.containerView addSubview:self.optInLabel]; [self.containerView addSubview:self.optInLabel];
[self.containerView addSubview:self.checkBoxButton]; [self.containerView addSubview:self.checkBoxButton];
[self addSubview:self.OKButton]; [self addSubview:self.OKButton];
...@@ -344,7 +361,11 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service"; ...@@ -344,7 +361,11 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service";
[super layoutSubviews]; [super layoutSubviews];
[self layoutTitleLabel]; [self layoutTitleLabel];
[self layoutImageView]; [self layoutImageView];
[self layoutTOSLabel]; if (@available(iOS 13.0, *)) {
[self layoutTOSTextView];
} else {
[self layoutLegacyTOSLabel];
}
[self layoutOptInLabel]; [self layoutOptInLabel];
[self layoutCheckBoxButton]; [self layoutCheckBoxButton];
[self layoutOKButtonAndContainerView]; [self layoutOKButtonAndContainerView];
...@@ -378,12 +399,27 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service"; ...@@ -378,12 +399,27 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service";
imageViewSize.width, imageViewSize.height)); imageViewSize.width, imageViewSize.height));
} }
- (void)layoutTOSLabel { - (void)layoutTOSTextView {
// The TOSTextView is centered and laid out below |imageView| as specified by
// kTOSTextViewTopPadding.
CGSize containerSize = self.containerView.bounds.size;
containerSize.height = CGFLOAT_MAX;
CGSize TOSTextViewSize = [self.TOSTextView sizeThatFits:containerSize];
CGFloat TOSTextViewTopPadding =
kTOSTextViewTopPadding[[self heightSizeClassIdiom]];
CGRect frame =
CGRectMake((containerSize.width - TOSTextViewSize.width) / 2.0,
CGRectGetMaxY(self.imageView.frame) + TOSTextViewTopPadding,
TOSTextViewSize.width, TOSTextViewSize.height);
self.TOSTextView.frame = AlignRectOriginAndSizeToPixels(frame);
}
- (void)layoutLegacyTOSLabel {
// The TOS label is centered and laid out below |imageView| as specified by // The TOS label is centered and laid out below |imageView| as specified by
// kTOSLabelTopPadding. // kTOSLabelTopPadding.
CGSize containerSize = self.containerView.bounds.size; CGSize containerSize = self.containerView.bounds.size;
containerSize.height = CGFLOAT_MAX; containerSize.height = CGFLOAT_MAX;
self.TOSLabel.frame = {CGPointZero, containerSize}; self.legacyTOSLabel.frame = {CGPointZero, containerSize};
NSString* TOSText = l10n_util::GetNSString(IDS_IOS_FIRSTRUN_AGREE_TO_TERMS); NSString* TOSText = l10n_util::GetNSString(IDS_IOS_FIRSTRUN_AGREE_TO_TERMS);
NSRange tosLinkTextRange = NSMakeRange(NSNotFound, 0); NSRange tosLinkTextRange = NSMakeRange(NSNotFound, 0);
TOSText = ParseStringWithTag(TOSText, &tosLinkTextRange, TOSText = ParseStringWithTag(TOSText, &tosLinkTextRange,
...@@ -392,7 +428,7 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service"; ...@@ -392,7 +428,7 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service";
DCHECK_NE(NSNotFound, static_cast<NSInteger>(tosLinkTextRange.location)); DCHECK_NE(NSNotFound, static_cast<NSInteger>(tosLinkTextRange.location));
DCHECK_NE(0u, tosLinkTextRange.length); DCHECK_NE(0u, tosLinkTextRange.length);
self.TOSLabel.text = TOSText; self.legacyTOSLabel.text = TOSText;
__weak WelcomeToChromeView* weakSelf = self; __weak WelcomeToChromeView* weakSelf = self;
ProceduralBlockWithURL action = ^(const GURL& url) { ProceduralBlockWithURL action = ^(const GURL& url) {
...@@ -406,15 +442,16 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service"; ...@@ -406,15 +442,16 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service";
} }
}; };
_TOSLabelLinkController = _legacyTOSLabelLinkController =
[[LabelLinkController alloc] initWithLabel:_TOSLabel action:action]; [[LabelLinkController alloc] initWithLabel:_legacyTOSLabel action:action];
[_TOSLabelLinkController addLinkWithRange:tosLinkTextRange [_legacyTOSLabelLinkController addLinkWithRange:tosLinkTextRange
url:GURL(kTermsOfServiceUrl)]; url:GURL(kTermsOfServiceUrl)];
[_TOSLabelLinkController setLinkColor:[UIColor colorNamed:kBlueColor]]; [_legacyTOSLabelLinkController setLinkColor:[UIColor colorNamed:kBlueColor]];
CGSize TOSLabelSize = [self.TOSLabel sizeThatFits:containerSize]; CGSize TOSLabelSize = [self.legacyTOSLabel sizeThatFits:containerSize];
CGFloat TOSLabelTopPadding = kTOSLabelTopPadding[[self heightSizeClassIdiom]]; CGFloat TOSLabelTopPadding =
self.TOSLabel.frame = AlignRectOriginAndSizeToPixels( kTOSTextViewTopPadding[[self heightSizeClassIdiom]];
self.legacyTOSLabel.frame = AlignRectOriginAndSizeToPixels(
CGRectMake((containerSize.width - TOSLabelSize.width) / 2.0, CGRectMake((containerSize.width - TOSLabelSize.width) / 2.0,
CGRectGetMaxY(self.imageView.frame) + TOSLabelTopPadding, CGRectGetMaxY(self.imageView.frame) + TOSLabelTopPadding,
TOSLabelSize.width, TOSLabelSize.height)); TOSLabelSize.width, TOSLabelSize.height));
...@@ -435,10 +472,17 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service"; ...@@ -435,10 +472,17 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service";
kOptInLabelPadding[[self heightSizeClassIdiom]]; kOptInLabelPadding[[self heightSizeClassIdiom]];
CGFloat optInLabelOriginX = CGFloat optInLabelOriginX =
base::i18n::IsRTL() ? 0.0f : optInLabelSidePadding; base::i18n::IsRTL() ? 0.0f : optInLabelSidePadding;
if (@available(iOS 13.0, *)) {
self.optInLabel.frame = AlignRectOriginAndSizeToPixels( self.optInLabel.frame = AlignRectOriginAndSizeToPixels(
CGRectMake(optInLabelOriginX, CGRectMake(optInLabelOriginX,
CGRectGetMaxY(self.TOSLabel.frame) + optInLabelTopPadding, CGRectGetMaxY(self.TOSTextView.frame) + optInLabelTopPadding,
optInLabelSize.width, optInLabelSize.height)); optInLabelSize.width, optInLabelSize.height));
} else {
self.optInLabel.frame = AlignRectOriginAndSizeToPixels(CGRectMake(
optInLabelOriginX,
CGRectGetMaxY(self.legacyTOSLabel.frame) + optInLabelTopPadding,
optInLabelSize.width, optInLabelSize.height));
}
} }
- (void)layoutCheckBoxButton { - (void)layoutCheckBoxButton {
...@@ -510,7 +554,11 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service"; ...@@ -510,7 +554,11 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service";
[self configureContainerView]; [self configureContainerView];
[self configureTitleLabel]; [self configureTitleLabel];
[self configureImageView]; [self configureImageView];
[self configureTOSLabel]; if (@available(iOS 13.0, *)) {
[self configureTOSTextView];
} else {
[self configureLegacyTOSLabel];
}
[self configureOptInLabel]; [self configureOptInLabel];
[self configureOKButton]; [self configureOKButton];
[self setNeedsLayout]; [self setNeedsLayout];
...@@ -533,10 +581,43 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service"; ...@@ -533,10 +581,43 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service";
sideLength, sideLength)); sideLength, sideLength));
} }
- (void)configureTOSLabel { - (void)configureTOSTextView {
self.TOSLabel.font = [[MDCTypography fontLoader] self.TOSTextView.scrollEnabled = NO;
regularFontOfSize:kTOSLabelFontSize[[self widthSizeClassIdiom]]]; self.TOSTextView.editable = NO;
self.TOSLabel.cr_lineHeight = kTOSLabelLineHeight[[self widthSizeClassIdiom]]; self.TOSTextView.adjustsFontForContentSizeCategory = YES;
self.TOSTextView.delegate = self;
self.TOSTextView.linkTextAttributes =
@{NSForegroundColorAttributeName : [UIColor colorNamed:kBlueColor]};
NSString* TOSText = l10n_util::GetNSString(IDS_IOS_FIRSTRUN_AGREE_TO_TERMS);
NSRange tosLinkTextRange = NSMakeRange(NSNotFound, 0);
TOSText = ParseStringWithTag(TOSText, &tosLinkTextRange,
@"BEGIN_LINK_TOS[ \t]*", @"[ \t]*END_LINK_TOS");
DCHECK_NE(NSNotFound, static_cast<NSInteger>(tosLinkTextRange.location));
DCHECK_NE(0u, tosLinkTextRange.length);
NSRange fullRange = NSMakeRange(0, TOSText.length);
NSURL* URL =
[NSURL URLWithString:base::SysUTF8ToNSString(kTermsOfServiceUrl)];
UIFont* font = [[MDCTypography fontLoader]
regularFontOfSize:kTOSTOSTextViewFontSize[[self widthSizeClassIdiom]]];
NSMutableParagraphStyle* style =
[[NSParagraphStyle defaultParagraphStyle] mutableCopy];
style.alignment = NSTextAlignmentCenter;
NSMutableAttributedString* attributedText =
[[NSMutableAttributedString alloc] initWithString:TOSText];
[attributedText addAttributes:@{
NSParagraphStyleAttributeName : style,
NSFontAttributeName : font
}
range:fullRange];
[attributedText addAttribute:NSLinkAttributeName
value:URL
range:tosLinkTextRange];
self.TOSTextView.attributedText = attributedText;
} }
- (void)configureOptInLabel { - (void)configureOptInLabel {
...@@ -546,6 +627,13 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service"; ...@@ -546,6 +627,13 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service";
kOptInLabelLineHeight[[self widthSizeClassIdiom]]; kOptInLabelLineHeight[[self widthSizeClassIdiom]];
} }
- (void)configureLegacyTOSLabel {
self.legacyTOSLabel.font = [[MDCTypography fontLoader]
regularFontOfSize:kTOSTOSTextViewFontSize[[self widthSizeClassIdiom]]];
self.legacyTOSLabel.cr_lineHeight =
kLegacyTOSLabelLineHeight[[self widthSizeClassIdiom]];
}
- (void)configureContainerView { - (void)configureContainerView {
CGFloat containerViewWidth = CGFloat containerViewWidth =
[self widthSizeClassIdiom] == COMPACT [self widthSizeClassIdiom] == COMPACT
...@@ -597,4 +685,18 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service"; ...@@ -597,4 +685,18 @@ const char kTermsOfServiceUrl[] = "internal://terms-of-service";
[self.delegate welcomeToChromeViewDidTapOKButton:self]; [self.delegate welcomeToChromeViewDidTapOKButton:self];
} }
#pragma mark - UITextViewDelegate
- (BOOL)textView:(TextViewSelectionDisabled*)textView
shouldInteractWithURL:(NSURL*)URL
inRange:(NSRange)characterRange
interaction:(UITextItemInteraction)interaction {
DCHECK(textView == self.TOSTextView);
DCHECK(GURL(base::SysNSStringToUTF8(URL.absoluteString)) ==
kTermsOfServiceUrl);
[self.delegate welcomeToChromeViewDidTapTOSLink];
// Returns NO as the app is handling the opening of the URL.
return NO;
}
@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