Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Side by Side Diff: ios/chrome/browser/ui/sad_tab/sad_tab_view.mm

Issue 2905953003: Use UITextView for better bulleted list presentation (Closed)
Patch Set: Review feedback Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "ios/chrome/browser/ui/sad_tab/sad_tab_view.h" 5 #import "ios/chrome/browser/ui/sad_tab/sad_tab_view.h"
6 6
7 #include "base/strings/sys_string_conversions.h" 7 #include "base/strings/sys_string_conversions.h"
8 #include "components/grit/components_scaled_resources.h" 8 #include "components/grit/components_scaled_resources.h"
9 #include "components/strings/grit/components_strings.h" 9 #include "components/strings/grit/components_strings.h"
10 #include "ios/chrome/browser/chrome_url_constants.h" 10 #include "ios/chrome/browser/chrome_url_constants.h"
(...skipping 12 matching lines...) Expand all
23 #include "url/gurl.h" 23 #include "url/gurl.h"
24 24
25 #if !defined(__has_feature) || !__has_feature(objc_arc) 25 #if !defined(__has_feature) || !__has_feature(objc_arc)
26 #error "This file requires ARC support." 26 #error "This file requires ARC support."
27 #endif 27 #endif
28 28
29 namespace { 29 namespace {
30 // Color constants. 30 // Color constants.
31 const CGFloat kBackgroundColorBrightness = 247.0f / 255.0f; 31 const CGFloat kBackgroundColorBrightness = 247.0f / 255.0f;
32 const CGFloat kTitleLabelTextColorBrightness = 22.0f / 255.0f; 32 const CGFloat kTitleLabelTextColorBrightness = 22.0f / 255.0f;
33 const CGFloat kMessageLabelTextColorBrightness = 80.0f / 255.0f; 33 const CGFloat kGeneralTextColorBrightness = 80.0f / 255.0f;
34 // Layout constants. 34 // Layout constants.
35 const UIEdgeInsets kLayoutInsets = {24.0f, 24.0f, 24.0f, 24.0f}; 35 const UIEdgeInsets kLayoutInsets = {24.0f, 24.0f, 24.0f, 24.0f};
36 const CGFloat kLayoutBoundsMaxWidth = 600.0f; 36 const CGFloat kLayoutBoundsMaxWidth = 600.0f;
37 const CGFloat kContainerViewLandscapeTopPadding = 22.0f; 37 const CGFloat kContainerViewLandscapeTopPadding = 22.0f;
38 const CGFloat kTitleLabelTopPadding = 26.0f; 38 const CGFloat kTitleLabelTopPadding = 26.0f;
39 const CGFloat kMessageLabelTopPadding = 16.0f; 39 const CGFloat kMessageTextViewTopPadding = 16.0f;
40 const CGFloat kFooterLabelTopPadding = 16.0f; 40 const CGFloat kFooterLabelTopPadding = 16.0f;
41 const CGFloat kActionButtonHeight = 48.0f; 41 const CGFloat kActionButtonHeight = 48.0f;
42 const CGFloat kActionButtonTopPadding = 16.0f; 42 const CGFloat kActionButtonTopPadding = 16.0f;
43 // Label font sizes. 43 // Label font sizes.
44 const CGFloat kTitleLabelFontSize = 23.0f; 44 const CGFloat kTitleLabelFontSize = 23.0f;
45 const CGFloat kMessageLabelFontSize = 14.0f; 45 const CGFloat kMessageTextViewFontSize = 14.0f;
46 const CGFloat kFooterLabelFontSize = 14.0f; 46 const CGFloat kFooterLabelFontSize = 14.0f;
47 // String constants for formatting bullets. 47 // Feedback message bullet indentation.
48 // "<5xSpace><Bullet><4xSpace><Content>". 48 const CGFloat kBulletIndent = 17.0f; // Left margin to bullet indent.
49 NSString* const kMessageLabelBulletPrefix = @" \u2022 "; 49 const CGFloat kBulletedTextIndent = 15.0f; // Bullet to text indent.
50 // "<newline>". 50 // Format for bulleted line (<tab><bullet><tab><string>).
51 NSString* const kMessageLabelBulletSuffix = @"\n"; 51 NSString* const kMessageTextViewBulletPrefix = @"\t\u2022\t";
52 // Separator for each new bullet line.
53 NSString* const kMessageTextViewBulletSuffix = @"\n";
52 // "<RTL Begin Indicator><NSString Token><RTL End Indicator>". 54 // "<RTL Begin Indicator><NSString Token><RTL End Indicator>".
53 NSString* const kMessageLabelBulletRTLFormat = @"\u202E%@\u202C"; 55 NSString* const kMessageTextViewBulletRTLFormat = @"\u202E%@\u202C";
54 } // namespace 56 } // namespace
55 57
56 @interface SadTabView () 58 @interface SadTabView ()
57 59
58 // Container view that displays all other subviews. 60 // Container view that displays all other subviews.
59 @property(nonatomic, readonly, strong) UIView* containerView; 61 @property(nonatomic, readonly, strong) UIView* containerView;
60 // Displays the Sad Tab face. 62 // Displays the Sad Tab face.
61 @property(nonatomic, readonly, strong) UIImageView* imageView; 63 @property(nonatomic, readonly, strong) UIImageView* imageView;
62 // Displays the Sad Tab title. 64 // Displays the Sad Tab title.
63 @property(nonatomic, readonly, strong) UILabel* titleLabel; 65 @property(nonatomic, readonly, strong) UILabel* titleLabel;
64 // Displays the Sad Tab message. 66 // Displays the Sad Tab message.
65 @property(nonatomic, readonly, strong) UILabel* messageLabel; 67 @property(nonatomic, readonly, strong) UITextView* messageTextView;
66 // Displays the Sad Tab footer message (including a link to more help). 68 // Displays the Sad Tab footer message (including a link to more help).
67 @property(nonatomic, readonly, strong) UILabel* footerLabel; 69 @property(nonatomic, readonly, strong) UILabel* footerLabel;
68 // Provides Link functionality to the footerLabel. 70 // Provides Link functionality to the footerLabel.
69 @property(nonatomic, readonly, strong) 71 @property(nonatomic, readonly, strong)
70 LabelLinkController* footerLabelLinkController; 72 LabelLinkController* footerLabelLinkController;
71 // Triggers a reload or feedback action. 73 // Triggers a reload or feedback action.
72 @property(nonatomic, readonly, strong) MDCFlatButton* actionButton; 74 @property(nonatomic, readonly, strong) MDCFlatButton* actionButton;
73 // The bounds of |containerView|, with a height updated to CGFLOAT_MAX to allow 75 // The bounds of |containerView|, with a height updated to CGFLOAT_MAX to allow
74 // text to be laid out using as many lines as necessary. 76 // text to be laid out using as many lines as necessary.
75 @property(nonatomic, readonly) CGRect containerBounds; 77 @property(nonatomic, readonly) CGRect containerBounds;
76 // Allows this view to perform navigation actions such as reloading. 78 // Allows this view to perform navigation actions such as reloading.
77 @property(nonatomic, readonly) web::NavigationManager* navigationManager; 79 @property(nonatomic, readonly) web::NavigationManager* navigationManager;
78 80
79 // Subview layout methods. Must be called in the following order, as subsequent 81 // Subview layout methods. Must be called in the following order, as subsequent
80 // layouts reference the values set in previous functions. 82 // layouts reference the values set in previous functions.
81 - (void)layoutImageView; 83 - (void)layoutImageView;
82 - (void)layoutTitleLabel; 84 - (void)layoutTitleLabel;
83 - (void)layoutMessageLabel; 85 - (void)layoutMessageTextView;
84 - (void)layoutFooterLabel; 86 - (void)layoutFooterLabel;
85 - (void)layoutActionButton; 87 - (void)layoutActionButton;
86 - (void)layoutContainerView; 88 - (void)layoutContainerView;
87 89
88 // Takes an array of strings and bulletizes them into a single multi-line string 90 // Takes an array of strings and bulletizes them into a single multi-line string
89 // for display. 91 // for display. The string has NSParagraphStyle attributes for tab alignment.
90 + (nonnull NSString*)bulletedStringFromStrings: 92 + (nonnull NSAttributedString*)bulletedAttributedStringFromStrings:
91 (nonnull NSArray<NSString*>*)strings; 93 (nonnull NSArray<NSString*>*)strings;
92 94
93 // Returns the appropriate title for the view, e.g. 'Aw Snap!'. 95 // Returns the appropriate title for the view, e.g. 'Aw Snap!'.
94 - (nonnull NSString*)titleLabelText; 96 - (nonnull NSString*)titleLabelText;
95 // Returns the appropriate message label body for the view, this will typically 97 // Returns the appropriate message text body for the view, this will typically
96 // be a larger body of explanation or help text. 98 // be a larger body of explanation or help text. Returns an attributed string
97 - (nonnull NSString*)messageLabelText; 99 // to allow for text formatting and layout to be applied to the returned string.
100 - (nonnull NSAttributedString*)messageTextViewAttributedText;
98 // Returns the full footer string containing a link, intended to be the last 101 // Returns the full footer string containing a link, intended to be the last
99 // piece of text. 102 // piece of text.
100 - (nonnull NSString*)footerLabelText; 103 - (nonnull NSString*)footerLabelText;
101 // Returns the substring of the footer string which is to be the underlined link 104 // Returns the substring of the footer string which is to be the underlined link
102 // text. (May be the entire footer label string). 105 // text. (May be the entire footer label string).
103 - (nonnull NSString*)footerLinkText; 106 - (nonnull NSString*)footerLinkText;
104 // Returns the string to be used for the main action button. 107 // Returns the string to be used for the main action button.
105 - (nonnull NSString*)buttonText; 108 - (nonnull NSString*)buttonText;
106 109
107 // Attaches a link controller to |label|, finding the |linkString| 110 // Attaches a link controller to |label|, finding the |linkString|
108 // within the |label| text to use as the link. 111 // within the |label| text to use as the link.
109 - (void)attachLinkControllerToLabel:(nonnull UILabel*)label 112 - (void)attachLinkControllerToLabel:(nonnull UILabel*)label
110 forLinkText:(nonnull NSString*)linkText; 113 forLinkText:(nonnull NSString*)linkText;
111 114
112 // The action selector for |_actionButton|. 115 // The action selector for |_actionButton|.
113 - (void)handleActionButtonTapped:(id)sender; 116 - (void)handleActionButtonTapped:(id)sender;
114 117
115 // Returns the desired background color. 118 // Returns the desired background color.
116 + (UIColor*)sadTabBackgroundColor; 119 + (UIColor*)sadTabBackgroundColor;
117 120
118 @end 121 @end
119 122
120 #pragma mark - SadTabView 123 #pragma mark - SadTabView
121 124
122 @implementation SadTabView 125 @implementation SadTabView
123 126
124 @synthesize imageView = _imageView; 127 @synthesize imageView = _imageView;
125 @synthesize containerView = _containerView; 128 @synthesize containerView = _containerView;
126 @synthesize titleLabel = _titleLabel; 129 @synthesize titleLabel = _titleLabel;
127 @synthesize messageLabel = _messageLabel; 130 @synthesize messageTextView = _messageTextView;
128 @synthesize footerLabel = _footerLabel; 131 @synthesize footerLabel = _footerLabel;
129 @synthesize footerLabelLinkController = _footerLabelLinkController; 132 @synthesize footerLabelLinkController = _footerLabelLinkController;
130 @synthesize actionButton = _actionButton; 133 @synthesize actionButton = _actionButton;
131 @synthesize mode = _mode; 134 @synthesize mode = _mode;
132 @synthesize navigationManager = _navigationManager; 135 @synthesize navigationManager = _navigationManager;
133 136
134 - (instancetype)initWithMode:(SadTabViewMode)mode 137 - (instancetype)initWithMode:(SadTabViewMode)mode
135 navigationManager:(web::NavigationManager*)navigationManager { 138 navigationManager:(web::NavigationManager*)navigationManager {
136 self = [super initWithFrame:CGRectZero]; 139 self = [super initWithFrame:CGRectZero];
137 if (self) { 140 if (self) {
(...skipping 14 matching lines...) Expand all
152 return nil; 155 return nil;
153 } 156 }
154 157
155 - (instancetype)initWithCoder:(NSCoder*)aDecoder { 158 - (instancetype)initWithCoder:(NSCoder*)aDecoder {
156 NOTREACHED(); 159 NOTREACHED();
157 return nil; 160 return nil;
158 } 161 }
159 162
160 #pragma mark - Text Utilities 163 #pragma mark - Text Utilities
161 164
162 + (nonnull NSString*)bulletedStringFromStrings: 165 + (nonnull NSAttributedString*)bulletedAttributedStringFromStrings:
163 (nonnull NSArray<NSString*>*)strings { 166 (nonnull NSArray<NSString*>*)strings {
164 // Ensures the bullet string is appropriately directional. 167 // Ensures the bullet string is appropriately directional.
165 NSString* directionalBulletPrefix = 168 NSString* directionalBulletPrefix =
166 base::i18n::IsRTL() 169 base::i18n::IsRTL()
167 ? [NSString stringWithFormat:kMessageLabelBulletRTLFormat, 170 ? [NSString stringWithFormat:kMessageTextViewBulletRTLFormat,
168 kMessageLabelBulletPrefix] 171 kMessageTextViewBulletPrefix]
169 : kMessageLabelBulletPrefix; 172 : kMessageTextViewBulletPrefix;
170 NSMutableString* bulletedString = [NSMutableString string]; 173
174 // Assemble the strings into a single string with each line preceded by a
175 // bullet point.
176 NSMutableString* bulletedString = [[NSMutableString alloc] init];
171 for (NSString* string in strings) { 177 for (NSString* string in strings) {
172 // If content line has been added to the bulletedString already, ensure the 178 // If content line has been added to the bulletedString already, ensure the
173 // suffix is applied, otherwise don't (e.g. don't for the first item). 179 // suffix is applied, otherwise don't (e.g. don't for the first item).
174 NSArray* newStringArray = 180 NSArray* newStringArray =
175 bulletedString.length 181 bulletedString.length
176 ? @[ kMessageLabelBulletSuffix, directionalBulletPrefix, string ] 182 ? @[ kMessageTextViewBulletSuffix, directionalBulletPrefix, string ]
177 : @[ directionalBulletPrefix, string ]; 183 : @[ directionalBulletPrefix, string ];
178 [bulletedString appendString:[newStringArray componentsJoinedByString:@""]]; 184 [bulletedString appendString:[newStringArray componentsJoinedByString:@""]];
179 } 185 }
180 DCHECK(bulletedString); 186
181 return bulletedString; 187 // Prepare a paragraph style that will allow for the alignment of lines of
188 // text separately to the alignment of the bullet-points.
189 NSMutableParagraphStyle* paragraphStyle =
190 [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
191 paragraphStyle.tabStops = @[
192 [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentNatural
193 location:kBulletIndent
194 options:@{}],
195 [[NSTextTab alloc] initWithTextAlignment:NSTextAlignmentNatural
196 location:kBulletIndent + kBulletedTextIndent
197 options:@{}]
198 ];
199 paragraphStyle.firstLineHeadIndent = 0.0f;
200 paragraphStyle.headIndent = kBulletIndent + kBulletedTextIndent;
201
202 // Use the paragraph style on the full string.
203 NSAttributedString* bulletedAttributedString = [[NSAttributedString alloc]
204 initWithString:bulletedString
205 attributes:@{NSParagraphStyleAttributeName : paragraphStyle}];
206
207 DCHECK(bulletedAttributedString);
208 return bulletedAttributedString;
182 } 209 }
183 210
184 #pragma mark - Label Text 211 #pragma mark - Label Text
185 212
186 - (nonnull NSString*)titleLabelText { 213 - (nonnull NSString*)titleLabelText {
187 NSString* label = nil; 214 NSString* label = nil;
188 switch (self.mode) { 215 switch (self.mode) {
189 case SadTabViewMode::RELOAD: 216 case SadTabViewMode::RELOAD:
190 label = l10n_util::GetNSString(IDS_SAD_TAB_TITLE); 217 label = l10n_util::GetNSString(IDS_SAD_TAB_TITLE);
191 break; 218 break;
192 case SadTabViewMode::FEEDBACK: 219 case SadTabViewMode::FEEDBACK:
193 label = l10n_util::GetNSString(IDS_SAD_TAB_RELOAD_TITLE); 220 label = l10n_util::GetNSString(IDS_SAD_TAB_RELOAD_TITLE);
194 break; 221 break;
195 } 222 }
196 DCHECK(label); 223 DCHECK(label);
197 return label; 224 return label;
198 } 225 }
199 226
200 - (nonnull NSString*)messageLabelText { 227 - (nonnull NSAttributedString*)messageTextViewAttributedText {
201 NSString* label = nil; 228 NSAttributedString* label = nil;
202 switch (self.mode) { 229 switch (self.mode) {
203 case SadTabViewMode::RELOAD: 230 case SadTabViewMode::RELOAD:
204 label = l10n_util::GetNSString(IDS_SAD_TAB_MESSAGE); 231 label = [[NSAttributedString alloc]
232 initWithString:l10n_util::GetNSString(IDS_SAD_TAB_MESSAGE)];
205 break; 233 break;
206 case SadTabViewMode::FEEDBACK: 234 case SadTabViewMode::FEEDBACK: {
207 label = l10n_util::GetNSString(IDS_SAD_TAB_RELOAD_TRY); 235 NSString* feedbackIntroductionString = [NSString
208 label = [label 236 stringWithFormat:@"%@\n\n",
209 stringByAppendingFormat: 237 l10n_util::GetNSString(IDS_SAD_TAB_RELOAD_TRY)];
210 @"\n\n%@", [[self class] bulletedStringFromStrings:@[ 238 NSMutableAttributedString* feedbackString =
211 l10n_util::GetNSString(IDS_SAD_TAB_RELOAD_CLOSE_NOTABS), 239 [[NSMutableAttributedString alloc]
212 l10n_util::GetNSString(IDS_SAD_TAB_RELOAD_INCOGNITO), 240 initWithString:feedbackIntroductionString];
213 l10n_util::GetNSString(IDS_SAD_TAB_RELOAD_RESTART_BROWSER), 241 NSAttributedString* bulletedListString =
214 l10n_util::GetNSString(IDS_SAD_TAB_RELOAD_RESTART_DEVICE) 242 [[self class] bulletedAttributedStringFromStrings:@[
215 ]]]; 243 l10n_util::GetNSString(IDS_SAD_TAB_RELOAD_CLOSE_NOTABS),
216 244 l10n_util::GetNSString(IDS_SAD_TAB_RELOAD_INCOGNITO),
245 l10n_util::GetNSString(IDS_SAD_TAB_RELOAD_RESTART_BROWSER),
246 l10n_util::GetNSString(IDS_SAD_TAB_RELOAD_RESTART_DEVICE)
247 ]];
248 [feedbackString appendAttributedString:bulletedListString];
249 label = feedbackString;
217 break; 250 break;
251 }
218 } 252 }
219 DCHECK(label); 253 DCHECK(label);
220 return label; 254 return label;
221 } 255 }
222 256
223 - (nonnull NSString*)footerLabelText { 257 - (nonnull NSString*)footerLabelText {
224 NSString* label = nil; 258 NSString* label = nil;
225 switch (self.mode) { 259 switch (self.mode) {
226 case SadTabViewMode::RELOAD: { 260 case SadTabViewMode::RELOAD: {
227 base::string16 footerLinkText( 261 base::string16 footerLinkText(
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 [_titleLabel setNumberOfLines:0]; 350 [_titleLabel setNumberOfLines:0];
317 [_titleLabel 351 [_titleLabel
318 setTextColor:[UIColor colorWithWhite:kTitleLabelTextColorBrightness 352 setTextColor:[UIColor colorWithWhite:kTitleLabelTextColorBrightness
319 alpha:1.0]]; 353 alpha:1.0]];
320 [_titleLabel setFont:[[MDFRobotoFontLoader sharedInstance] 354 [_titleLabel setFont:[[MDFRobotoFontLoader sharedInstance]
321 regularFontOfSize:kTitleLabelFontSize]]; 355 regularFontOfSize:kTitleLabelFontSize]];
322 } 356 }
323 return _titleLabel; 357 return _titleLabel;
324 } 358 }
325 359
326 - (UILabel*)messageLabel { 360 - (UITextView*)messageTextView {
327 if (!_messageLabel) { 361 if (!_messageTextView) {
328 _messageLabel = [[UILabel alloc] initWithFrame:CGRectZero]; 362 _messageTextView = [[UITextView alloc] initWithFrame:CGRectZero];
329 [_messageLabel setBackgroundColor:self.backgroundColor]; 363 [_messageTextView setBackgroundColor:self.backgroundColor];
330 [_messageLabel setText:[self messageLabelText]]; 364 [_messageTextView setAttributedText:[self messageTextViewAttributedText]];
331 [_messageLabel setLineBreakMode:NSLineBreakByWordWrapping]; 365 _messageTextView.textContainer.lineFragmentPadding = 0.0f;
332 [_messageLabel setNumberOfLines:0]; 366 [_messageTextView
333 [_messageLabel 367 setTextColor:[UIColor colorWithWhite:kGeneralTextColorBrightness
334 setTextColor:[UIColor colorWithWhite:kMessageLabelTextColorBrightness
335 alpha:1.0]]; 368 alpha:1.0]];
336 [_messageLabel setFont:[[MDFRobotoFontLoader sharedInstance] 369 [_messageTextView setFont:[[MDFRobotoFontLoader sharedInstance]
337 regularFontOfSize:kMessageLabelFontSize]]; 370 regularFontOfSize:kMessageTextViewFontSize]];
338 } 371 }
339 return _messageLabel; 372 return _messageTextView;
340 } 373 }
341 374
342 - (UILabel*)footerLabel { 375 - (UILabel*)footerLabel {
343 if (!_footerLabel) { 376 if (!_footerLabel) {
344 _footerLabel = [[UILabel alloc] initWithFrame:CGRectZero]; 377 _footerLabel = [[UILabel alloc] initWithFrame:CGRectZero];
345 [_footerLabel setBackgroundColor:self.backgroundColor]; 378 [_footerLabel setBackgroundColor:self.backgroundColor];
346 [_footerLabel setNumberOfLines:0]; 379 [_footerLabel setNumberOfLines:0];
347 [_footerLabel setFont:[[MDFRobotoFontLoader sharedInstance] 380 [_footerLabel setFont:[[MDFRobotoFontLoader sharedInstance]
348 regularFontOfSize:kFooterLabelFontSize]]; 381 regularFontOfSize:kFooterLabelFontSize]];
349 [_footerLabel 382 [_footerLabel
350 setTextColor:[UIColor colorWithWhite:kMessageLabelTextColorBrightness 383 setTextColor:[UIColor colorWithWhite:kGeneralTextColorBrightness
351 alpha:1.0]]; 384 alpha:1.0]];
352 385
353 [_footerLabel setText:[self footerLabelText]]; 386 [_footerLabel setText:[self footerLabelText]];
354 [self attachLinkControllerToLabel:_footerLabel 387 [self attachLinkControllerToLabel:_footerLabel
355 forLinkText:[self footerLinkText]]; 388 forLinkText:[self footerLinkText]];
356 } 389 }
357 return _footerLabel; 390 return _footerLabel;
358 } 391 }
359 392
360 - (UIButton*)actionButton { 393 - (UIButton*)actionButton {
(...skipping 30 matching lines...) Expand all
391 [super willMoveToSuperview:newSuperview]; 424 [super willMoveToSuperview:newSuperview];
392 425
393 if (self.containerView.superview) { 426 if (self.containerView.superview) {
394 DCHECK_EQ(self.containerView.superview, self); 427 DCHECK_EQ(self.containerView.superview, self);
395 return; 428 return;
396 } 429 }
397 430
398 [self addSubview:self.containerView]; 431 [self addSubview:self.containerView];
399 [self.containerView addSubview:self.imageView]; 432 [self.containerView addSubview:self.imageView];
400 [self.containerView addSubview:self.titleLabel]; 433 [self.containerView addSubview:self.titleLabel];
401 [self.containerView addSubview:self.messageLabel]; 434 [self.containerView addSubview:self.messageTextView];
402 [self.containerView addSubview:self.footerLabel]; 435 [self.containerView addSubview:self.footerLabel];
403 } 436 }
404 437
405 - (void)layoutSubviews { 438 - (void)layoutSubviews {
406 [super layoutSubviews]; 439 [super layoutSubviews];
407 440
408 [self layoutImageView]; 441 [self layoutImageView];
409 [self layoutTitleLabel]; 442 [self layoutTitleLabel];
410 [self layoutMessageLabel]; 443 [self layoutMessageTextView];
411 [self layoutFooterLabel]; 444 [self layoutFooterLabel];
412 [self layoutActionButton]; 445 [self layoutActionButton];
413 [self layoutContainerView]; 446 [self layoutContainerView];
414 } 447 }
415 448
416 - (CGSize)sizeThatFits:(CGSize)size { 449 - (CGSize)sizeThatFits:(CGSize)size {
417 return size; 450 return size;
418 } 451 }
419 452
420 - (void)layoutImageView { 453 - (void)layoutImageView {
421 LayoutRect imageViewLayout = LayoutRectZero; 454 LayoutRect imageViewLayout = LayoutRectZero;
422 imageViewLayout.boundingWidth = CGRectGetWidth(self.containerBounds); 455 imageViewLayout.boundingWidth = CGRectGetWidth(self.containerBounds);
423 imageViewLayout.size = self.imageView.bounds.size; 456 imageViewLayout.size = self.imageView.bounds.size;
424 self.imageView.frame = 457 self.imageView.frame =
425 AlignRectOriginAndSizeToPixels(LayoutRectGetRect(imageViewLayout)); 458 AlignRectOriginAndSizeToPixels(LayoutRectGetRect(imageViewLayout));
426 } 459 }
427 460
428 - (void)layoutTitleLabel { 461 - (void)layoutTitleLabel {
429 CGRect containerBounds = self.containerBounds; 462 CGRect containerBounds = self.containerBounds;
430 LayoutRect titleLabelLayout = LayoutRectZero; 463 LayoutRect titleLabelLayout = LayoutRectZero;
431 titleLabelLayout.boundingWidth = CGRectGetWidth(containerBounds); 464 titleLabelLayout.boundingWidth = CGRectGetWidth(containerBounds);
432 titleLabelLayout.size = [self.titleLabel sizeThatFits:containerBounds.size]; 465 titleLabelLayout.size = [self.titleLabel sizeThatFits:containerBounds.size];
433 titleLabelLayout.position.originY = 466 titleLabelLayout.position.originY =
434 CGRectGetMaxY(self.imageView.frame) + kTitleLabelTopPadding; 467 CGRectGetMaxY(self.imageView.frame) + kTitleLabelTopPadding;
435 self.titleLabel.frame = 468 self.titleLabel.frame =
436 AlignRectOriginAndSizeToPixels(LayoutRectGetRect(titleLabelLayout)); 469 AlignRectOriginAndSizeToPixels(LayoutRectGetRect(titleLabelLayout));
437 } 470 }
438 471
439 - (void)layoutMessageLabel { 472 - (void)layoutMessageTextView {
440 CGRect containerBounds = self.containerBounds; 473 CGRect containerBounds = self.containerBounds;
441 LayoutRect messageLabelLayout = LayoutRectZero; 474 LayoutRect messageTextViewLayout = LayoutRectZero;
442 messageLabelLayout.boundingWidth = CGRectGetWidth(containerBounds); 475 messageTextViewLayout.boundingWidth = CGRectGetWidth(containerBounds);
443 messageLabelLayout.size = 476 messageTextViewLayout.size =
444 [self.messageLabel sizeThatFits:containerBounds.size]; 477 [self.messageTextView sizeThatFits:containerBounds.size];
445 messageLabelLayout.position.originY = 478 messageTextViewLayout.position.originY =
446 CGRectGetMaxY(self.titleLabel.frame) + kMessageLabelTopPadding; 479 CGRectGetMaxY(self.titleLabel.frame) + kMessageTextViewTopPadding;
447 self.messageLabel.frame = 480 self.messageTextView.frame =
448 AlignRectOriginAndSizeToPixels(LayoutRectGetRect(messageLabelLayout)); 481 AlignRectOriginAndSizeToPixels(LayoutRectGetRect(messageTextViewLayout));
449 } 482 }
450 483
451 - (void)layoutFooterLabel { 484 - (void)layoutFooterLabel {
452 CGRect containerBounds = self.containerBounds; 485 CGRect containerBounds = self.containerBounds;
453 LayoutRect footerLabelLayout = LayoutRectZero; 486 LayoutRect footerLabelLayout = LayoutRectZero;
454 footerLabelLayout.boundingWidth = CGRectGetWidth(containerBounds); 487 footerLabelLayout.boundingWidth = CGRectGetWidth(containerBounds);
455 footerLabelLayout.size = [self.footerLabel sizeThatFits:containerBounds.size]; 488 footerLabelLayout.size = [self.footerLabel sizeThatFits:containerBounds.size];
456 footerLabelLayout.position.originY = 489 footerLabelLayout.position.originY =
457 CGRectGetMaxY(self.messageLabel.frame) + kFooterLabelTopPadding; 490 CGRectGetMaxY(self.messageTextView.frame) + kFooterLabelTopPadding;
458 self.footerLabel.frame = 491 self.footerLabel.frame =
459 AlignRectOriginAndSizeToPixels(LayoutRectGetRect(footerLabelLayout)); 492 AlignRectOriginAndSizeToPixels(LayoutRectGetRect(footerLabelLayout));
460 } 493 }
461 494
462 - (void)layoutActionButton { 495 - (void)layoutActionButton {
463 CGRect containerBounds = self.containerBounds; 496 CGRect containerBounds = self.containerBounds;
464 BOOL isIPadIdiom = IsIPadIdiom(); 497 BOOL isIPadIdiom = IsIPadIdiom();
465 BOOL isPortrait = IsPortrait(); 498 BOOL isPortrait = IsPortrait();
466 BOOL shouldAddActionButtonToContainer = isIPadIdiom || !isPortrait; 499 BOOL shouldAddActionButtonToContainer = isIPadIdiom || !isPortrait;
467 LayoutRect actionButtonLayout = LayoutRectZero; 500 LayoutRect actionButtonLayout = LayoutRectZero;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 break; 565 break;
533 } 566 }
534 }; 567 };
535 } 568 }
536 569
537 + (UIColor*)sadTabBackgroundColor { 570 + (UIColor*)sadTabBackgroundColor {
538 return [UIColor colorWithWhite:kBackgroundColorBrightness alpha:1.0]; 571 return [UIColor colorWithWhite:kBackgroundColorBrightness alpha:1.0];
539 } 572 }
540 573
541 @end 574 @end
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698