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

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

Issue 2617993002: Animate IOS Share extension button. (Closed)
Patch Set: feedback 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
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
91 // Animates the button |sender| by replaceing its string to "Added", then call
92 // completion.
93 - (void)animateButtonPressed:(UIButton*)sender
94 withCompletion:(void (^)(void))completion;
95
77 @end 96 @end
78 97
79 @implementation ShareExtensionView 98 @implementation ShareExtensionView
80 99
81 @synthesize titleLabel = _titleLabel; 100 @synthesize titleLabel = _titleLabel;
82 @synthesize URLLabel = _URLLabel; 101 @synthesize URLLabel = _URLLabel;
102 @synthesize readingListButton = _readingListButton;
83 @synthesize screenshotView = _screenshotView; 103 @synthesize screenshotView = _screenshotView;
84 @synthesize itemStack = _itemStack; 104 @synthesize itemStack = _itemStack;
85 105
86 #pragma mark - Lifecycle 106 #pragma mark - Lifecycle
87 107
88 - (instancetype)initWithActionTarget: 108 - (instancetype)initWithActionTarget:
89 (id<ShareExtensionViewActionTarget>)target { 109 (id<ShareExtensionViewActionTarget>)target {
90 self = [super initWithFrame:CGRectZero]; 110 self = [super initWithFrame:CGRectZero];
91 if (self) { 111 if (self) {
92 DCHECK(target); 112 DCHECK(target);
93 _target = target; 113 _target = target;
114 _dismissed = NO;
94 115
95 [self.layer setCornerRadius:kCornerRadius]; 116 [self.layer setCornerRadius:kCornerRadius];
96 [self setClipsToBounds:YES]; 117 [self setClipsToBounds:YES];
97 UIBlurEffect* blurEffect = 118 UIBlurEffect* blurEffect =
98 [UIBlurEffect effectWithStyle:UIBlurEffectStyleExtraLight]; 119 [UIBlurEffect effectWithStyle:UIBlurEffectStyleExtraLight];
99 UIVibrancyEffect* vibrancyEffect = 120 UIVibrancyEffect* vibrancyEffect =
100 [UIVibrancyEffect effectForBlurEffect:blurEffect]; 121 [UIVibrancyEffect effectForBlurEffect:blurEffect];
101 122
102 self.backgroundColor = [UIColor colorWithWhite:242.0f / 255.0f alpha:1]; 123 self.backgroundColor = [UIColor colorWithWhite:242.0f / 255.0f alpha:1];
103 124
104 // Add the blur effect to the whole widget. 125 // Add the blur effect to the whole widget.
105 UIVisualEffectView* blurringView = 126 UIVisualEffectView* blurringView =
106 [[UIVisualEffectView alloc] initWithEffect:blurEffect]; 127 [[UIVisualEffectView alloc] initWithEffect:blurEffect];
107 [self addSubview:blurringView]; 128 [self addSubview:blurringView];
108 ui_util::ConstrainAllSidesOfViewToView(self, blurringView); 129 ui_util::ConstrainAllSidesOfViewToView(self, blurringView);
109 [[blurringView layer] setCornerRadius:kCornerRadius]; 130 [[blurringView layer] setCornerRadius:kCornerRadius];
110 [blurringView setClipsToBounds:YES]; 131 [blurringView setClipsToBounds:YES];
111 132
112 NSString* addToReadingListTitle = NSLocalizedString( 133 NSString* addToReadingListTitle = NSLocalizedString(
113 @"IDS_IOS_ADD_READING_LIST_SHARE_EXTENSION", 134 @"IDS_IOS_ADD_READING_LIST_SHARE_EXTENSION",
114 @"The add to reading list button text in share extension."); 135 @"The add to reading list button text in share extension.");
115 UIButton* readingListButton = [self 136 self.readingListButton =
116 buttonWithTitle:addToReadingListTitle 137 [self buttonWithTitle:addToReadingListTitle
117 selector:@selector( 138 selector:@selector(addToReadingListPressed:)];
118 shareExtensionViewDidSelectAddToReadingList:)];
119 139
120 NSString* addToBookmarksTitle = NSLocalizedString( 140 NSString* addToBookmarksTitle = NSLocalizedString(
121 @"IDS_IOS_ADD_BOOKMARKS_SHARE_EXTENSION", 141 @"IDS_IOS_ADD_BOOKMARKS_SHARE_EXTENSION",
122 @"The Add to bookmarks button text in share extension."); 142 @"The Add to bookmarks button text in share extension.");
123 UIButton* bookmarksButton = [self 143 UIButton* bookmarksButton =
124 buttonWithTitle:addToBookmarksTitle 144 [self buttonWithTitle:addToBookmarksTitle
125 selector:@selector(shareExtensionViewDidSelectAddToBookmarks:)]; 145 selector:@selector(addToBookmarksPressed:)];
126 146
127 UIStackView* contentStack = [[UIStackView alloc] initWithArrangedSubviews:@[ 147 UIStackView* contentStack = [[UIStackView alloc] initWithArrangedSubviews:@[
128 [self navigationBar], [self dividerViewWithVibrancy:vibrancyEffect], 148 [self navigationBar], [self dividerViewWithVibrancy:vibrancyEffect],
129 [self sharedItemView], [self dividerViewWithVibrancy:vibrancyEffect], 149 [self sharedItemView], [self dividerViewWithVibrancy:vibrancyEffect],
130 readingListButton, [self dividerViewWithVibrancy:vibrancyEffect], 150 self.readingListButton, [self dividerViewWithVibrancy:vibrancyEffect],
131 bookmarksButton 151 bookmarksButton
132 ]]; 152 ]];
133 [contentStack setAxis:UILayoutConstraintAxisVertical]; 153 [contentStack setAxis:UILayoutConstraintAxisVertical];
134 [[blurringView contentView] addSubview:contentStack]; 154 [[blurringView contentView] addSubview:contentStack];
135 155
136 [blurringView setTranslatesAutoresizingMaskIntoConstraints:NO]; 156 [blurringView setTranslatesAutoresizingMaskIntoConstraints:NO];
137 [contentStack setTranslatesAutoresizingMaskIntoConstraints:NO]; 157 [contentStack setTranslatesAutoresizingMaskIntoConstraints:NO];
138 158
139 ui_util::ConstrainAllSidesOfViewToView([blurringView contentView], 159 ui_util::ConstrainAllSidesOfViewToView([blurringView contentView],
140 contentStack); 160 contentStack);
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 269
250 - (UIButton*)buttonWithTitle:(NSString*)title selector:(SEL)selector { 270 - (UIButton*)buttonWithTitle:(NSString*)title selector:(SEL)selector {
251 UIButton* systemButton = [UIButton buttonWithType:UIButtonTypeSystem]; 271 UIButton* systemButton = [UIButton buttonWithType:UIButtonTypeSystem];
252 UIColor* systemColor = [systemButton titleColorForState:UIControlStateNormal]; 272 UIColor* systemColor = [systemButton titleColorForState:UIControlStateNormal];
253 273
254 UIButton* button = [[ShareExtensionButton alloc] initWithFrame:CGRectZero]; 274 UIButton* button = [[ShareExtensionButton alloc] initWithFrame:CGRectZero];
255 [button setTitle:title forState:UIControlStateNormal]; 275 [button setTitle:title forState:UIControlStateNormal];
256 [button setTitleColor:systemColor forState:UIControlStateNormal]; 276 [button setTitleColor:systemColor forState:UIControlStateNormal];
257 [[button titleLabel] setFont:[UIFont systemFontOfSize:kButtonFontSize]]; 277 [[button titleLabel] setFont:[UIFont systemFontOfSize:kButtonFontSize]];
258 [button setTranslatesAutoresizingMaskIntoConstraints:NO]; 278 [button setTranslatesAutoresizingMaskIntoConstraints:NO];
259 [button addTarget:_target 279 [button addTarget:self
260 action:selector 280 action:selector
261 forControlEvents:UIControlEventTouchUpInside]; 281 forControlEvents:UIControlEventTouchUpInside];
262 [button.heightAnchor constraintEqualToConstant:kButtonHeight].active = YES; 282 [button.heightAnchor constraintEqualToConstant:kButtonHeight].active = YES;
263 return button; 283 return button;
264 } 284 }
265 285
266 - (UINavigationBar*)navigationBar { 286 - (UINavigationBar*)navigationBar {
267 // Create the navigation bar. 287 // Create the navigation bar.
268 UINavigationBar* navigationBar = 288 UINavigationBar* navigationBar =
269 [[UINavigationBar alloc] initWithFrame:CGRectZero]; 289 [[UINavigationBar alloc] initWithFrame:CGRectZero];
270 [[navigationBar layer] setCornerRadius:kCornerRadius]; 290 [[navigationBar layer] setCornerRadius:kCornerRadius];
271 [navigationBar setClipsToBounds:YES]; 291 [navigationBar setClipsToBounds:YES];
272 292
273 // Create an empty image to replace the standard gray background of the 293 // Create an empty image to replace the standard gray background of the
274 // UINavigationBar. 294 // UINavigationBar.
275 UIImage* emptyImage = [[UIImage alloc] init]; 295 UIImage* emptyImage = [[UIImage alloc] init];
276 [navigationBar setBackgroundImage:emptyImage 296 [navigationBar setBackgroundImage:emptyImage
277 forBarMetrics:UIBarMetricsDefault]; 297 forBarMetrics:UIBarMetricsDefault];
278 [navigationBar setShadowImage:emptyImage]; 298 [navigationBar setShadowImage:emptyImage];
279 [navigationBar setTranslucent:YES]; 299 [navigationBar setTranslucent:YES];
280 [navigationBar setTranslatesAutoresizingMaskIntoConstraints:NO]; 300 [navigationBar setTranslatesAutoresizingMaskIntoConstraints:NO];
281 301
282 UIBarButtonItem* cancelButton = [[UIBarButtonItem alloc] 302 UIBarButtonItem* cancelButton = [[UIBarButtonItem alloc]
283 initWithBarButtonSystemItem:UIBarButtonSystemItemCancel 303 initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
284 target:_target 304 target:self
285 action:@selector( 305 action:@selector(cancelPressed:)];
286 shareExtensionViewDidSelectCancel:)];
287 306
288 NSString* appName = 307 NSString* appName =
289 [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]; 308 [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"];
290 UINavigationItem* titleItem = 309 UINavigationItem* titleItem =
291 [[UINavigationItem alloc] initWithTitle:appName]; 310 [[UINavigationItem alloc] initWithTitle:appName];
292 [titleItem setLeftBarButtonItem:cancelButton]; 311 [titleItem setLeftBarButtonItem:cancelButton];
293 [titleItem setHidesBackButton:YES]; 312 [titleItem setHidesBackButton:YES];
294 [navigationBar pushNavigationItem:titleItem animated:NO]; 313 [navigationBar pushNavigationItem:titleItem animated:NO];
295 return navigationBar; 314 return navigationBar;
296 } 315 }
297 316
317 - (void)addToReadingListPressed:(UIButton*)sender {
318 if (_dismissed) {
319 return;
320 }
321 _dismissed = YES;
322 [self animateButtonPressed:sender
323 withCompletion:^{
324 [_target shareExtensionViewDidSelectAddToReadingList:sender];
325 }];
326 }
327
328 - (void)addToBookmarksPressed:(UIButton*)sender {
329 if (_dismissed) {
330 return;
331 }
332 _dismissed = YES;
333 [self animateButtonPressed:sender
334 withCompletion:^{
335 [_target shareExtensionViewDidSelectAddToBookmarks:sender];
336 }];
337 }
338
339 - (void)animateButtonPressed:(UIButton*)sender
340 withCompletion:(void (^)(void))completion {
341 NSString* addedString =
342 NSLocalizedString(@"IDS_IOS_ADDED_ITEM_SHARE_EXTENSION",
343 @"Button label after being pressed.");
344 NSString* addedCheckedString =
345 [addedString stringByAppendingString:@" \u2713"];
346 // Create a label with the same style as the split animation between the text
347 // and the checkmark.
348 UILabel* addedLabel = [[UILabel alloc] initWithFrame:CGRectZero];
349 [addedLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
350 [addedLabel setText:addedString];
351 [self addSubview:addedLabel];
352 [addedLabel setFont:[sender titleLabel].font];
353 [addedLabel setTextColor:[sender titleColorForState:UIControlStateNormal]];
354 [addedLabel.leadingAnchor
355 constraintEqualToAnchor:[sender titleLabel].leadingAnchor]
356 .active = YES;
357 [addedLabel.centerYAnchor
358 constraintEqualToAnchor:[sender titleLabel].centerYAnchor]
359 .active = YES;
360 [addedLabel setAlpha:0];
361
362 void (^step3ShowCheck)() = ^{
363 [UIView animateWithDuration:ui_util::kAnimationDuration
364 animations:^{
365 [addedLabel setAlpha:0];
366 [sender setAlpha:1];
367 }
368 completion:^(BOOL finished) {
369 if (completion) {
370 completion();
371 }
372 }];
373 };
374
375 void (^step2ShowTextWithoutCheck)() = ^{
376 [sender setTitle:addedCheckedString forState:UIControlStateNormal];
377 [UIView animateWithDuration:ui_util::kAnimationDuration
378 animations:^{
379 [addedLabel setAlpha:1];
380 }
381 completion:^(BOOL finished) {
382 step3ShowCheck();
383 }];
384 };
385
386 void (^step1HideText)() = ^{
387 [UIView animateWithDuration:ui_util::kAnimationDuration
388 animations:^{
389 [sender setAlpha:0];
390 }
391 completion:^(BOOL finished) {
392 step2ShowTextWithoutCheck();
393 }];
394 };
395 step1HideText();
396 }
397
398 - (void)cancelPressed:(UIButton*)sender {
399 if (_dismissed) {
400 return;
401 }
402 _dismissed = YES;
403 [_target shareExtensionViewDidSelectCancel:sender];
404 }
405
298 #pragma mark - Content getters and setters. 406 #pragma mark - Content getters and setters.
299 407
300 - (void)setURL:(NSURL*)URL { 408 - (void)setURL:(NSURL*)URL {
301 [[self URLLabel] setText:[URL absoluteString]]; 409 [[self URLLabel] setText:[URL absoluteString]];
302 } 410 }
303 411
304 - (void)setTitle:(NSString*)title { 412 - (void)setTitle:(NSString*)title {
305 [[self titleLabel] setText:title]; 413 [[self titleLabel] setText:title];
306 } 414 }
307 415
308 - (void)setScreenshot:(UIImage*)screenshot { 416 - (void)setScreenshot:(UIImage*)screenshot {
309 [[self screenshotView] setHidden:NO]; 417 [[self screenshotView] setHidden:NO];
310 [[self screenshotView] setImage:screenshot]; 418 [[self screenshotView] setImage:screenshot];
311 [[self itemStack] addArrangedSubview:[self screenshotView]]; 419 [[self itemStack] addArrangedSubview:[self screenshotView]];
312 } 420 }
313 421
314 @end 422 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698