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

Side by Side Diff: ios/chrome/share_extension/share_extension_view.mm

Issue 2617993002: Animate IOS Share extension button. (Closed)
Patch Set: real cleaning Created 3 years, 11 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 | ios/chrome/share_extension/share_view_controller.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/share_extension/share_extension_view.h" 5 #import "ios/chrome/share_extension/share_extension_view.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #import "ios/chrome/share_extension/ui_util.h" 8 #import "ios/chrome/share_extension/ui_util.h"
9 9
10 #if !defined(__has_feature) || !__has_feature(objc_arc) 10 #if !defined(__has_feature) || !__has_feature(objc_arc)
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 else 44 else
45 self.backgroundColor = [UIColor clearColor]; 45 self.backgroundColor = [UIColor clearColor];
46 } 46 }
47 47
48 @end 48 @end
49 49
50 #pragma mark - Share Extension View 50 #pragma mark - Share Extension View
51 51
52 @interface ShareExtensionView () { 52 @interface ShareExtensionView () {
53 __weak id<ShareExtensionViewActionTarget> _target; 53 __weak id<ShareExtensionViewActionTarget> _target;
54
55 // Track if a button has been pressed. All button pressing will have no effect
56 // if |_dismissed| is YES.
57 BOOL _dismissed;
54 } 58 }
55 59
56 // Keep strong references of the views that need to be updated. 60 // Keep strong references of the views that need to be updated.
57 @property(nonatomic, strong) UILabel* titleLabel; 61 @property(nonatomic, strong) UILabel* titleLabel;
58 @property(nonatomic, strong) UILabel* URLLabel; 62 @property(nonatomic, strong) UILabel* URLLabel;
63 @property(nonatomic, strong) UIButton* readingListButton;
59 @property(nonatomic, strong) UIImageView* screenshotView; 64 @property(nonatomic, strong) UIImageView* screenshotView;
60 @property(nonatomic, strong) UIStackView* itemStack; 65 @property(nonatomic, strong) UIStackView* itemStack;
61 66
62 // View creation helpers. 67 // View creation helpers.
63 // Returns a view containing the shared items (title, URL, screenshot). This 68 // Returns a view containing the shared items (title, URL, screenshot). This
64 // method will set the ivars. 69 // method will set the ivars.
65 - (UIView*)sharedItemView; 70 - (UIView*)sharedItemView;
66 71
67 // Returns a button containing the with title |title| and action |selector| on 72 // Returns a button containing the with title |title| and action |selector| on
68 // |_target|. 73 // |_target|.
69 - (UIButton*)buttonWithTitle:(NSString*)title selector:(SEL)selector; 74 - (UIButton*)buttonWithTitle:(NSString*)title selector:(SEL)selector;
70 75
71 // Returns a view containing a divider with vibrancy effect. 76 // Returns a view containing a divider with vibrancy effect.
72 - (UIView*)dividerViewWithVibrancy:(UIVisualEffect*)vibrancyEffect; 77 - (UIView*)dividerViewWithVibrancy:(UIVisualEffect*)vibrancyEffect;
73 78
74 // Returns a navigationBar. 79 // Returns a navigationBar.
75 - (UINavigationBar*)navigationBar; 80 - (UINavigationBar*)navigationBar;
76 81
82 // Called when "Read Later" button has been pressed.
83 - (void)addToReadingListPressed:(UIButton*)sender;
84
85 // Called when "Add to bookmarks" button has been pressed.
86 - (void)addToBookmarksPressed:(UIButton*)sender;
87
88 // Called when "Cancel" button has been pressed.
89 - (void)cancelPressed:(UIButton*)sender;
90
77 @end 91 @end
78 92
79 @implementation ShareExtensionView 93 @implementation ShareExtensionView
80 94
81 @synthesize titleLabel = _titleLabel; 95 @synthesize titleLabel = _titleLabel;
82 @synthesize URLLabel = _URLLabel; 96 @synthesize URLLabel = _URLLabel;
97 @synthesize readingListButton = _readingListButton;
83 @synthesize screenshotView = _screenshotView; 98 @synthesize screenshotView = _screenshotView;
84 @synthesize itemStack = _itemStack; 99 @synthesize itemStack = _itemStack;
85 100
86 #pragma mark - Lifecycle 101 #pragma mark - Lifecycle
87 102
88 - (instancetype)initWithActionTarget: 103 - (instancetype)initWithActionTarget:
89 (id<ShareExtensionViewActionTarget>)target { 104 (id<ShareExtensionViewActionTarget>)target {
90 self = [super initWithFrame:CGRectZero]; 105 self = [super initWithFrame:CGRectZero];
91 if (self) { 106 if (self) {
92 DCHECK(target); 107 DCHECK(target);
93 _target = target; 108 _target = target;
109 _dismissed = NO;
94 110
95 [self.layer setCornerRadius:kCornerRadius]; 111 [self.layer setCornerRadius:kCornerRadius];
96 [self setClipsToBounds:YES]; 112 [self setClipsToBounds:YES];
97 UIBlurEffect* blurEffect = 113 UIBlurEffect* blurEffect =
98 [UIBlurEffect effectWithStyle:UIBlurEffectStyleExtraLight]; 114 [UIBlurEffect effectWithStyle:UIBlurEffectStyleExtraLight];
99 UIVibrancyEffect* vibrancyEffect = 115 UIVibrancyEffect* vibrancyEffect =
100 [UIVibrancyEffect effectForBlurEffect:blurEffect]; 116 [UIVibrancyEffect effectForBlurEffect:blurEffect];
101 117
102 self.backgroundColor = [UIColor colorWithWhite:242.0f / 255.0f alpha:1]; 118 self.backgroundColor = [UIColor colorWithWhite:242.0f / 255.0f alpha:1];
103 119
104 // Add the blur effect to the whole widget. 120 // Add the blur effect to the whole widget.
105 UIVisualEffectView* blurringView = 121 UIVisualEffectView* blurringView =
106 [[UIVisualEffectView alloc] initWithEffect:blurEffect]; 122 [[UIVisualEffectView alloc] initWithEffect:blurEffect];
107 [self addSubview:blurringView]; 123 [self addSubview:blurringView];
108 ui_util::ConstrainAllSidesOfViewToView(self, blurringView); 124 ui_util::ConstrainAllSidesOfViewToView(self, blurringView);
109 [[blurringView layer] setCornerRadius:kCornerRadius]; 125 [[blurringView layer] setCornerRadius:kCornerRadius];
110 [blurringView setClipsToBounds:YES]; 126 [blurringView setClipsToBounds:YES];
111 127
112 NSString* addToReadingListTitle = NSLocalizedString( 128 NSString* addToReadingListTitle = NSLocalizedString(
113 @"IDS_IOS_ADD_READING_LIST_SHARE_EXTENSION", 129 @"IDS_IOS_ADD_READING_LIST_SHARE_EXTENSION",
114 @"The add to reading list button text in share extension."); 130 @"The add to reading list button text in share extension.");
115 UIButton* readingListButton = [self 131 self.readingListButton =
116 buttonWithTitle:addToReadingListTitle 132 [self buttonWithTitle:addToReadingListTitle
117 selector:@selector( 133 selector:@selector(addToReadingListPressed:)];
118 shareExtensionViewDidSelectAddToReadingList:)];
119 134
120 NSString* addToBookmarksTitle = NSLocalizedString( 135 NSString* addToBookmarksTitle = NSLocalizedString(
121 @"IDS_IOS_ADD_BOOKMARKS_SHARE_EXTENSION", 136 @"IDS_IOS_ADD_BOOKMARKS_SHARE_EXTENSION",
122 @"The Add to bookmarks button text in share extension."); 137 @"The Add to bookmarks button text in share extension.");
123 UIButton* bookmarksButton = [self 138 UIButton* bookmarksButton =
124 buttonWithTitle:addToBookmarksTitle 139 [self buttonWithTitle:addToBookmarksTitle
125 selector:@selector(shareExtensionViewDidSelectAddToBookmarks:)]; 140 selector:@selector(addToBookmarksPressed:)];
126 141
127 UIStackView* contentStack = [[UIStackView alloc] initWithArrangedSubviews:@[ 142 UIStackView* contentStack = [[UIStackView alloc] initWithArrangedSubviews:@[
128 [self navigationBar], [self dividerViewWithVibrancy:vibrancyEffect], 143 [self navigationBar], [self dividerViewWithVibrancy:vibrancyEffect],
129 [self sharedItemView], [self dividerViewWithVibrancy:vibrancyEffect], 144 [self sharedItemView], [self dividerViewWithVibrancy:vibrancyEffect],
130 readingListButton, [self dividerViewWithVibrancy:vibrancyEffect], 145 self.readingListButton, [self dividerViewWithVibrancy:vibrancyEffect],
131 bookmarksButton 146 bookmarksButton
132 ]]; 147 ]];
133 [contentStack setAxis:UILayoutConstraintAxisVertical]; 148 [contentStack setAxis:UILayoutConstraintAxisVertical];
134 [[blurringView contentView] addSubview:contentStack]; 149 [[blurringView contentView] addSubview:contentStack];
135 150
136 [blurringView setTranslatesAutoresizingMaskIntoConstraints:NO]; 151 [blurringView setTranslatesAutoresizingMaskIntoConstraints:NO];
137 [contentStack setTranslatesAutoresizingMaskIntoConstraints:NO]; 152 [contentStack setTranslatesAutoresizingMaskIntoConstraints:NO];
138 153
139 ui_util::ConstrainAllSidesOfViewToView([blurringView contentView], 154 ui_util::ConstrainAllSidesOfViewToView([blurringView contentView],
140 contentStack); 155 contentStack);
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 264
250 - (UIButton*)buttonWithTitle:(NSString*)title selector:(SEL)selector { 265 - (UIButton*)buttonWithTitle:(NSString*)title selector:(SEL)selector {
251 UIButton* systemButton = [UIButton buttonWithType:UIButtonTypeSystem]; 266 UIButton* systemButton = [UIButton buttonWithType:UIButtonTypeSystem];
252 UIColor* systemColor = [systemButton titleColorForState:UIControlStateNormal]; 267 UIColor* systemColor = [systemButton titleColorForState:UIControlStateNormal];
253 268
254 UIButton* button = [[ShareExtensionButton alloc] initWithFrame:CGRectZero]; 269 UIButton* button = [[ShareExtensionButton alloc] initWithFrame:CGRectZero];
255 [button setTitle:title forState:UIControlStateNormal]; 270 [button setTitle:title forState:UIControlStateNormal];
256 [button setTitleColor:systemColor forState:UIControlStateNormal]; 271 [button setTitleColor:systemColor forState:UIControlStateNormal];
257 [[button titleLabel] setFont:[UIFont systemFontOfSize:kButtonFontSize]]; 272 [[button titleLabel] setFont:[UIFont systemFontOfSize:kButtonFontSize]];
258 [button setTranslatesAutoresizingMaskIntoConstraints:NO]; 273 [button setTranslatesAutoresizingMaskIntoConstraints:NO];
259 [button addTarget:_target 274 [button addTarget:self
260 action:selector 275 action:selector
261 forControlEvents:UIControlEventTouchUpInside]; 276 forControlEvents:UIControlEventTouchUpInside];
262 [button.heightAnchor constraintEqualToConstant:kButtonHeight].active = YES; 277 [button.heightAnchor constraintEqualToConstant:kButtonHeight].active = YES;
263 return button; 278 return button;
264 } 279 }
265 280
266 - (UINavigationBar*)navigationBar { 281 - (UINavigationBar*)navigationBar {
267 // Create the navigation bar. 282 // Create the navigation bar.
268 UINavigationBar* navigationBar = 283 UINavigationBar* navigationBar =
269 [[UINavigationBar alloc] initWithFrame:CGRectZero]; 284 [[UINavigationBar alloc] initWithFrame:CGRectZero];
270 [[navigationBar layer] setCornerRadius:kCornerRadius]; 285 [[navigationBar layer] setCornerRadius:kCornerRadius];
271 [navigationBar setClipsToBounds:YES]; 286 [navigationBar setClipsToBounds:YES];
272 287
273 // Create an empty image to replace the standard gray background of the 288 // Create an empty image to replace the standard gray background of the
274 // UINavigationBar. 289 // UINavigationBar.
275 UIImage* emptyImage = [[UIImage alloc] init]; 290 UIImage* emptyImage = [[UIImage alloc] init];
276 [navigationBar setBackgroundImage:emptyImage 291 [navigationBar setBackgroundImage:emptyImage
277 forBarMetrics:UIBarMetricsDefault]; 292 forBarMetrics:UIBarMetricsDefault];
278 [navigationBar setShadowImage:emptyImage]; 293 [navigationBar setShadowImage:emptyImage];
279 [navigationBar setTranslucent:YES]; 294 [navigationBar setTranslucent:YES];
280 [navigationBar setTranslatesAutoresizingMaskIntoConstraints:NO]; 295 [navigationBar setTranslatesAutoresizingMaskIntoConstraints:NO];
281 296
282 UIBarButtonItem* cancelButton = [[UIBarButtonItem alloc] 297 UIBarButtonItem* cancelButton = [[UIBarButtonItem alloc]
283 initWithBarButtonSystemItem:UIBarButtonSystemItemCancel 298 initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
284 target:_target 299 target:self
285 action:@selector( 300 action:@selector(cancelPressed:)];
286 shareExtensionViewDidSelectCancel:)];
287 301
288 NSString* appName = 302 NSString* appName =
289 [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]; 303 [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"];
290 UINavigationItem* titleItem = 304 UINavigationItem* titleItem =
291 [[UINavigationItem alloc] initWithTitle:appName]; 305 [[UINavigationItem alloc] initWithTitle:appName];
292 [titleItem setLeftBarButtonItem:cancelButton]; 306 [titleItem setLeftBarButtonItem:cancelButton];
293 [titleItem setHidesBackButton:YES]; 307 [titleItem setHidesBackButton:YES];
294 [navigationBar pushNavigationItem:titleItem animated:NO]; 308 [navigationBar pushNavigationItem:titleItem animated:NO];
295 return navigationBar; 309 return navigationBar;
296 } 310 }
297 311
312 - (void)addToReadingListPressed:(UIButton*)sender {
313 if (_dismissed) {
314 return;
315 }
316 _dismissed = YES;
317 [self animateButtonPressed:sender
318 withCompletion:^{
319 [_target shareExtensionViewDidSelectAddToReadingList:sender];
320 }];
321 }
322
323 - (void)animateButtonPressed:(UIButton*)sender
gambard 2017/01/06 16:23:54 Add method definition and comment.
Olivier 2017/01/06 16:42:16 Done.
324 withCompletion:(void (^)(void))completion {
325 NSString* addedString =
326 NSLocalizedString(@"IDS_IOS_ADDED_ITEM_SHARE_EXTENSION",
gambard 2017/01/06 16:23:54 Did you add IDS_IOS_ADDED_ITEM_SHARE_EXTENSION? I
Olivier 2017/01/06 16:42:15 I did... in another tree... :(
327 @"Button label after being pressed.");
328 NSString* addedCheckedString =
329 [addedString stringByAppendingString:@" \u2713"];
330 // Create a label with the same style as the split animation between the text
331 // and the checkmark.
332 UILabel* addedLabel = [[UILabel alloc] initWithFrame:CGRectZero];
333 [addedLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
334 [addedLabel setText:addedString];
335 [self addSubview:addedLabel];
336 [addedLabel setFont:[sender titleLabel].font];
337 [addedLabel setTextColor:[sender titleLabel].textColor];
gambard 2017/01/06 16:23:54 You can use [sender titleColorForState:UIControlSt
Olivier 2017/01/06 16:42:15 Done.
338 [addedLabel.leadingAnchor
gambard 2017/01/06 16:23:54 This will align the beginning of the "Added" with
Olivier 2017/01/06 16:42:15 There is no mock on what is centered. What is true
339 constraintEqualToAnchor:[sender titleLabel].leadingAnchor]
340 .active = YES;
341 [addedLabel.centerYAnchor
342 constraintEqualToAnchor:[sender titleLabel].centerYAnchor]
343 .active = YES;
344 [addedLabel setAlpha:0];
345
346 void (^step3ShowCheck)() = ^{
347 [UIView animateWithDuration:ui_util::kAnimationDuration
348 animations:^{
349 [addedLabel setAlpha:0];
350 [sender setAlpha:1];
351 }
352 completion:^(BOOL finished) {
353 completion();
gambard 2017/01/06 16:23:54 You don't check for nullability?
Olivier 2017/01/06 16:42:16 Done.
354 }];
355 };
356
357 void (^step2ShowTextWithoutCheck)() = ^{
358 [sender setTitle:addedCheckedString forState:UIControlStateNormal];
359 [UIView animateWithDuration:ui_util::kAnimationDuration
360 animations:^{
361 [addedLabel setAlpha:1];
362 }
363 completion:^(BOOL finished) {
364 step3ShowCheck();
365 }];
366 };
367
368 void (^step1HideText)() = ^{
369 [UIView animateWithDuration:ui_util::kAnimationDuration
370 animations:^{
371 [sender setAlpha:0];
372 }
373 completion:^(BOOL finished) {
374 step2ShowTextWithoutCheck();
375 }];
376 };
377 step1HideText();
378 }
379
380 - (void)addToBookmarksPressed:(UIButton*)sender {
gambard 2017/01/06 16:23:54 Please position this function before animateButton
Olivier 2017/01/06 16:42:16 Done.
381 if (_dismissed) {
382 return;
383 }
384 _dismissed = YES;
385 [self animateButtonPressed:sender
386 withCompletion:^{
387 [_target shareExtensionViewDidSelectAddToBookmarks:sender];
388 }];
389 }
390
391 - (void)cancelPressed:(UIButton*)sender {
392 if (_dismissed) {
393 return;
394 }
395 _dismissed = YES;
396 [_target shareExtensionViewDidSelectCancel:sender];
397 }
398
298 #pragma mark - Content getters and setters. 399 #pragma mark - Content getters and setters.
299 400
300 - (void)setURL:(NSURL*)URL { 401 - (void)setURL:(NSURL*)URL {
301 [[self URLLabel] setText:[URL absoluteString]]; 402 [[self URLLabel] setText:[URL absoluteString]];
302 } 403 }
303 404
304 - (void)setTitle:(NSString*)title { 405 - (void)setTitle:(NSString*)title {
305 [[self titleLabel] setText:title]; 406 [[self titleLabel] setText:title];
306 } 407 }
307 408
308 - (void)setScreenshot:(UIImage*)screenshot { 409 - (void)setScreenshot:(UIImage*)screenshot {
309 [[self screenshotView] setHidden:NO]; 410 [[self screenshotView] setHidden:NO];
310 [[self screenshotView] setImage:screenshot]; 411 [[self screenshotView] setImage:screenshot];
311 [[self itemStack] addArrangedSubview:[self screenshotView]]; 412 [[self itemStack] addArrangedSubview:[self screenshotView]];
312 } 413 }
313 414
314 @end 415 @end
OLDNEW
« no previous file with comments | « no previous file | ios/chrome/share_extension/share_view_controller.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698