Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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/search_widget_extension/search_widget_view.h" | 5 #import "ios/chrome/search_widget_extension/search_widget_view.h" |
| 6 | |
| 7 #include "base/logging.h" | 6 #include "base/logging.h" |
| 7 #import "ios/chrome/search_widget_extension/ui_util.h" | |
| 8 | 8 |
| 9 #if !defined(__has_feature) || !__has_feature(objc_arc) | 9 #if !defined(__has_feature) || !__has_feature(objc_arc) |
| 10 #error "This file requires ARC support." | 10 #error "This file requires ARC support." |
| 11 #endif | 11 #endif |
| 12 | 12 |
| 13 namespace { | 13 namespace { |
| 14 | 14 |
| 15 const CGFloat kCursorHeight = 40; | 15 const CGFloat kContentMargin = 16; |
| 16 const CGFloat kCursorWidth = 2; | 16 const CGFloat kURLButtonMargin = 10; |
| 17 const CGFloat kCursorHorizontalPadding = 10; | 17 const CGFloat kActionButtonSize = 55; |
| 18 const CGFloat kCursorVerticalPadding = 10; | 18 const CGFloat kIconSize = 35; |
| 19 const CGFloat kFakeboxHorizontalPadding = 40; | 19 const CGFloat kMaxContentSize = 421; |
| 20 const CGFloat kFakeboxVerticalPadding = 40; | 20 const CGFloat kIconSpacing = 5; |
| 21 | 21 |
| 22 } // namespace | 22 } // namespace |
| 23 | 23 |
| 24 @interface SearchWidgetView () { | 24 @interface SearchWidgetView () |
| 25 __weak id<SearchWidgetViewActionTarget> _target; | 25 |
| 26 } | 26 // The target for actions in the view. |
| 27 | 27 @property(nonatomic, weak) id<SearchWidgetViewActionTarget> target; |
| 28 @property(nonatomic, copy) NSString* copiedURL; | 28 // The copied URL label containing the URL or a placeholder text. |
| 29 @property(nonatomic, strong) UILabel* copiedURLLabel; | 29 @property(nonatomic, strong) UILabel* copiedURLLabel; |
| 30 @property(nonatomic, weak) UIView* cursor; | 30 // The copued URL title label containing the title of the copied URL button. |
| 31 | 31 @property(nonatomic, strong) UILabel* openCopiedURLTitleLabel; |
| 32 // Creates and adds a fake omnibox with blinking cursor to the view and sets the | 32 // The hairline view shown between the action and copied URL views. |
| 33 // class cursor property. | 33 @property(nonatomic, strong) UIView* hairlineView; |
| 34 - (void)addFakebox; | 34 // The button shown when there is a copied URL to open. |
| 35 @property(nonatomic, strong) UIButton* copiedButtonView; | |
| 36 // The primary effect view of the widget. Add views here for a more opaque | |
| 37 // appearance. | |
| 38 @property(nonatomic, strong) UIVisualEffectView* primaryEffectView; | |
| 39 // The secondary effect view of the widget. Add views here for a more | |
| 40 // transparent appearance. | |
| 41 @property(nonatomic, strong) UIVisualEffectView* secondaryEffectView; | |
| 42 // The constraints to be activated when the copiedURL section is visible. | |
| 43 @property(nonatomic, strong) | |
| 44 NSArray<NSLayoutConstraint*>* visibleCopiedURLConstraints; | |
| 45 // The constraints to be activated when the copiedURL section is hidden. | |
| 46 @property(nonatomic, strong) | |
| 47 NSArray<NSLayoutConstraint*>* hiddenCopiedURLConstraints; | |
| 48 | |
| 49 // Sets up the widget UI. | |
| 50 - (void)createUI; | |
| 51 | |
| 52 // Creates the view for the action buttons. | |
| 53 - (UIView*)newActionsView; | |
| 54 | |
| 55 // Creates the view for the copiedURL section. | |
| 56 - (void)initializeOpenCopiedURLSectionUsingTopAnchor:(NSLayoutAnchor*)topAnchor; | |
| 35 | 57 |
| 36 @end | 58 @end |
| 37 | 59 |
| 38 @implementation SearchWidgetView | 60 @implementation SearchWidgetView |
| 39 | 61 |
| 40 @synthesize copiedURL = _copiedURL; | 62 @synthesize target = _target; |
| 63 @synthesize copiedURLVisible = _copiedURLVisible; | |
| 64 @synthesize copiedURLString = _copiedURLString; | |
| 41 @synthesize copiedURLLabel = _copiedURLLabel; | 65 @synthesize copiedURLLabel = _copiedURLLabel; |
| 42 | 66 @synthesize openCopiedURLTitleLabel = _openCopiedURLTitleLabel; |
| 43 @synthesize cursor = _cursor; | 67 @synthesize hairlineView = _hairlineView; |
| 44 | 68 @synthesize copiedButtonView = _copiedButtonView; |
| 45 - (instancetype)initWithActionTarget:(id<SearchWidgetViewActionTarget>)target { | 69 @synthesize primaryEffectView = _primaryEffectView; |
| 70 @synthesize secondaryEffectView = _secondaryEffectView; | |
| 71 @synthesize visibleCopiedURLConstraints = _visibleCopiedURLConstraints; | |
| 72 @synthesize hiddenCopiedURLConstraints = _hiddenCopiedURLConstraints; | |
| 73 | |
| 74 - (instancetype)initWithActionTarget:(id<SearchWidgetViewActionTarget>)target | |
| 75 primaryVibrancyEffect:(UIVibrancyEffect*)primaryVibrancyEffect | |
| 76 secondaryVibrancyEffect: | |
| 77 (UIVibrancyEffect*)secondaryVibrancyEffect { | |
| 46 self = [super initWithFrame:CGRectZero]; | 78 self = [super initWithFrame:CGRectZero]; |
| 47 if (self) { | 79 if (self) { |
| 48 DCHECK(target); | 80 DCHECK(target); |
| 49 _target = target; | 81 _target = target; |
| 50 [self addFakebox]; | 82 _primaryEffectView = |
| 83 [[UIVisualEffectView alloc] initWithEffect:primaryVibrancyEffect]; | |
| 84 _secondaryEffectView = | |
| 85 [[UIVisualEffectView alloc] initWithEffect:secondaryVibrancyEffect]; | |
| 86 _copiedURLVisible = YES; | |
| 87 [self createUI]; | |
| 88 [self updateCopiedURLUI]; | |
| 51 } | 89 } |
| 52 return self; | 90 return self; |
| 53 } | 91 } |
| 54 | 92 |
| 55 - (void)addFakebox { | 93 #pragma mark - property overrides |
| 56 UIView* fakebox = [[UIView alloc] initWithFrame:CGRectZero]; | 94 |
| 57 | 95 - (void)setCopiedURLVisible:(BOOL)copiedURLVisible { |
| 96 _copiedURLVisible = copiedURLVisible; | |
| 97 [self updateCopiedURLUI]; | |
| 98 } | |
| 99 | |
| 100 - (void)setCopiedURLString:(NSString*)copiedURL { | |
| 101 _copiedURLString = copiedURL; | |
| 102 [self updateCopiedURLUI]; | |
| 103 } | |
| 104 | |
| 105 #pragma mark - UI creation | |
| 106 | |
| 107 - (void)createUI { | |
| 108 for (UIVisualEffectView* effectView in | |
| 109 @[ self.primaryEffectView, self.secondaryEffectView ]) { | |
| 110 [self addSubview:effectView]; | |
| 111 effectView.translatesAutoresizingMaskIntoConstraints = NO; | |
| 112 [NSLayoutConstraint | |
| 113 activateConstraints:ui_util::CreateSameConstraints(self, effectView)]; | |
| 114 } | |
| 115 | |
| 116 UIView* actionsView = [self newActionsView]; | |
| 117 [self initializeOpenCopiedURLSectionUsingTopAnchor:actionsView.bottomAnchor]; | |
| 118 } | |
| 119 | |
| 120 - (UIView*)newActionsView { | |
| 121 // Views added to different effect views need to be constrained to each other. | |
| 122 // This is made easier by putting all the constraints into an array and | |
|
marq (ping after 24h)
2017/05/09 16:01:43
Activating constraints all at once is *somewhat* m
lody
2017/05/09 16:17:57
As seen offline, this is functionally necessary. P
marq (ping after 24h)
2017/05/10 10:48:42
My rough suggestion:
"The vibrancy effects requir
lody
2017/05/10 12:54:02
perfect! thanks.
| |
| 123 // activating them all at once after adding all the views. | |
| 124 NSMutableArray<NSLayoutConstraint*>* constraintArray = [NSMutableArray array]; | |
|
marq (ping after 24h)
2017/05/10 10:48:42
Rename to 'constraints' (prefer not to include typ
lody
2017/05/10 12:54:02
Done.
| |
| 125 | |
| 126 UIStackView* actionRow = [[UIStackView alloc] initWithArrangedSubviews:@[ | |
| 127 [self newActionViewWithTitle:@"New Search" | |
| 128 imageName:@"quick_action_search" | |
| 129 actionSelector:@selector(openSearch:) | |
| 130 constraintArray:constraintArray], | |
| 131 [self newActionViewWithTitle:@"Incognito Search" | |
| 132 imageName:@"quick_action_incognito_search" | |
| 133 actionSelector:@selector(openIncognito:) | |
| 134 constraintArray:constraintArray], | |
| 135 [self newActionViewWithTitle:@"Voice Search" | |
| 136 imageName:@"quick_action_voice_search" | |
| 137 actionSelector:@selector(openVoice:) | |
| 138 constraintArray:constraintArray], | |
| 139 [self newActionViewWithTitle:@"Scan QR/Bar Code" | |
| 140 imageName:@"quick_action_camera_search" | |
| 141 actionSelector:@selector(openQRCode:) | |
| 142 constraintArray:constraintArray], | |
| 143 ]]; | |
| 144 | |
| 145 actionRow.axis = UILayoutConstraintAxisHorizontal; | |
| 146 actionRow.alignment = UIStackViewAlignmentTop; | |
| 147 actionRow.distribution = UIStackViewDistributionFillEqually; | |
| 148 actionRow.spacing = kIconSpacing; | |
| 149 actionRow.layoutMargins = | |
| 150 UIEdgeInsetsMake(0, kContentMargin, 0, kContentMargin); | |
| 151 actionRow.layoutMarginsRelativeArrangement = YES; | |
| 152 actionRow.translatesAutoresizingMaskIntoConstraints = NO; | |
| 153 | |
| 154 [self.secondaryEffectView.contentView addSubview:actionRow]; | |
| 155 | |
| 156 // These constraints stretch the action row to the full width of the widget. | |
| 157 // Their priority is < UILayoutPriorityRequired so that they can break when | |
| 158 // the view is larger than kMaxContentSize. | |
| 159 NSLayoutConstraint* actionsLeftConstraint = [actionRow.leftAnchor | |
| 160 constraintEqualToAnchor:self.secondaryEffectView.leftAnchor]; | |
| 161 actionsLeftConstraint.priority = UILayoutPriorityDefaultHigh; | |
| 162 | |
| 163 NSLayoutConstraint* actionsRightConstraint = [actionRow.rightAnchor | |
| 164 constraintEqualToAnchor:self.secondaryEffectView.rightAnchor]; | |
| 165 actionsRightConstraint.priority = UILayoutPriorityDefaultHigh; | |
| 166 | |
| 167 // This constraint sets the top alignment for the action row. Its priority is | |
| 168 // < UILayoutPriorityRequired so that it can break in favor of the | |
| 169 // centerYAnchor rule (on the next line) when the copiedURL section is hidden. | |
| 170 NSLayoutConstraint* actionsTopConstraint = [actionRow.topAnchor | |
| 171 constraintEqualToAnchor:self.secondaryEffectView.topAnchor | |
| 172 constant:kContentMargin]; | |
| 173 actionsTopConstraint.priority = UILayoutPriorityDefaultHigh; | |
| 174 | |
| 175 self.hiddenCopiedURLConstraints = @[ [actionRow.centerYAnchor | |
| 176 constraintEqualToAnchor:self.secondaryEffectView.centerYAnchor] ]; | |
| 177 | |
| 178 [constraintArray addObjectsFromArray:@[ | |
| 179 [actionRow.centerXAnchor | |
| 180 constraintEqualToAnchor:self.secondaryEffectView.centerXAnchor], | |
| 181 [actionRow.widthAnchor constraintLessThanOrEqualToConstant:kMaxContentSize], | |
| 182 actionsLeftConstraint, | |
| 183 actionsRightConstraint, | |
| 184 actionsTopConstraint, | |
| 185 ]]; | |
| 186 | |
| 187 [NSLayoutConstraint activateConstraints:constraintArray]; | |
| 188 | |
| 189 return actionRow; | |
| 190 } | |
| 191 | |
| 192 - (UIView*)newActionViewWithTitle:(NSString*)title | |
| 193 imageName:(NSString*)imageName | |
| 194 actionSelector:(SEL)actionSelector | |
| 195 constraintArray: | |
| 196 (NSMutableArray<NSLayoutConstraint*>*)constraintArray { | |
| 197 UIView* circleView = [[UIView alloc] initWithFrame:CGRectZero]; | |
| 198 circleView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.05]; | |
| 199 circleView.layer.cornerRadius = kActionButtonSize / 2; | |
| 200 | |
| 201 [constraintArray addObjectsFromArray:@[ | |
| 202 [circleView.widthAnchor constraintEqualToConstant:kActionButtonSize], | |
| 203 [circleView.heightAnchor constraintEqualToConstant:kActionButtonSize] | |
| 204 ]]; | |
| 205 | |
| 206 UILabel* labelView = [[UILabel alloc] initWithFrame:CGRectZero]; | |
| 207 labelView.text = title; | |
| 208 labelView.numberOfLines = 0; | |
| 209 labelView.textAlignment = NSTextAlignmentCenter; | |
| 210 labelView.font = [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote]; | |
| 211 [labelView | |
| 212 setContentCompressionResistancePriority:UILayoutPriorityRequired | |
| 213 forAxis:UILayoutConstraintAxisVertical]; | |
| 214 | |
| 215 UIStackView* stack = | |
| 216 [[UIStackView alloc] initWithArrangedSubviews:@[ circleView, labelView ]]; | |
| 217 stack.axis = UILayoutConstraintAxisVertical; | |
| 218 stack.spacing = kIconSpacing; | |
| 219 stack.alignment = UIStackViewAlignmentCenter; | |
| 220 stack.translatesAutoresizingMaskIntoConstraints = NO; | |
| 221 | |
| 222 // A transparent button constrained to the same size as the stack is added to | |
| 223 // handle taps on the stack view. | |
| 224 UIButton* actionButton = [[UIButton alloc] initWithFrame:CGRectZero]; | |
| 225 actionButton.backgroundColor = [UIColor clearColor]; | |
| 226 [actionButton addTarget:self.target | |
| 227 action:actionSelector | |
| 228 forControlEvents:UIControlEventTouchUpInside]; | |
| 229 actionButton.translatesAutoresizingMaskIntoConstraints = NO; | |
| 230 [self addSubview:actionButton]; | |
| 231 [constraintArray | |
| 232 addObjectsFromArray:ui_util::CreateSameConstraints(actionButton, stack)]; | |
| 233 | |
| 234 UIImage* iconImage = [UIImage imageNamed:imageName]; | |
| 235 UIImageView* icon = [[UIImageView alloc] initWithImage:iconImage]; | |
| 236 icon.translatesAutoresizingMaskIntoConstraints = NO; | |
| 237 | |
| 238 [constraintArray addObjectsFromArray:@[ | |
| 239 [icon.widthAnchor constraintEqualToConstant:kIconSize], | |
| 240 [icon.heightAnchor constraintEqualToConstant:kIconSize], | |
| 241 [icon.centerXAnchor constraintEqualToAnchor:circleView.centerXAnchor], | |
| 242 [icon.centerYAnchor constraintEqualToAnchor:circleView.centerYAnchor], | |
| 243 ]]; | |
| 244 [self.primaryEffectView.contentView addSubview:icon]; | |
| 245 | |
| 246 return stack; | |
| 247 } | |
| 248 | |
| 249 - (void)initializeOpenCopiedURLSectionUsingTopAnchor: | |
| 250 (NSLayoutAnchor*)topAnchor { | |
| 251 self.hairlineView = [[UIView alloc] initWithFrame:CGRectZero]; | |
| 252 self.hairlineView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.05]; | |
| 253 self.hairlineView.translatesAutoresizingMaskIntoConstraints = NO; | |
| 254 [self.secondaryEffectView.contentView addSubview:self.hairlineView]; | |
| 255 | |
| 256 self.copiedButtonView = [[UIButton alloc] initWithFrame:CGRectZero]; | |
| 257 self.copiedButtonView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.05]; | |
| 258 self.copiedButtonView.layer.cornerRadius = 5; | |
| 259 self.copiedButtonView.translatesAutoresizingMaskIntoConstraints = NO; | |
| 260 [self.secondaryEffectView.contentView addSubview:self.copiedButtonView]; | |
| 261 [self.copiedButtonView addTarget:self.target | |
| 262 action:@selector(openCopiedURL:) | |
| 263 forControlEvents:UIControlEventTouchUpInside]; | |
| 264 | |
| 265 self.openCopiedURLTitleLabel = [[UILabel alloc] initWithFrame:CGRectZero]; | |
| 266 self.openCopiedURLTitleLabel.textAlignment = NSTextAlignmentCenter; | |
| 267 self.openCopiedURLTitleLabel.translatesAutoresizingMaskIntoConstraints = NO; | |
| 268 self.openCopiedURLTitleLabel.font = | |
| 269 [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline]; | |
| 270 [self.primaryEffectView.contentView addSubview:self.openCopiedURLTitleLabel]; | |
| 271 | |
| 272 self.copiedURLLabel = [[UILabel alloc] initWithFrame:CGRectZero]; | |
| 273 self.copiedURLLabel.textAlignment = NSTextAlignmentCenter; | |
| 274 self.copiedURLLabel.font = | |
| 275 [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote]; | |
| 276 self.copiedURLLabel.translatesAutoresizingMaskIntoConstraints = NO; | |
| 277 [self.secondaryEffectView.contentView addSubview:self.copiedURLLabel]; | |
| 278 | |
| 279 self.visibleCopiedURLConstraints = @[ | |
| 280 [self.hairlineView.topAnchor constraintEqualToAnchor:topAnchor | |
| 281 constant:kContentMargin], | |
| 282 [self.hairlineView.leftAnchor | |
| 283 constraintEqualToAnchor:self.secondaryEffectView.leftAnchor], | |
| 284 [self.hairlineView.rightAnchor | |
| 285 constraintEqualToAnchor:self.secondaryEffectView.rightAnchor], | |
| 286 [self.hairlineView.heightAnchor constraintEqualToConstant:0.5], | |
| 287 | |
| 288 [self.copiedButtonView.centerXAnchor | |
| 289 constraintEqualToAnchor:self.secondaryEffectView.centerXAnchor], | |
| 290 [self.copiedButtonView.widthAnchor | |
| 291 constraintEqualToAnchor:self.secondaryEffectView.widthAnchor | |
| 292 constant:-2 * kContentMargin], | |
| 293 [self.copiedButtonView.topAnchor | |
| 294 constraintEqualToAnchor:self.hairlineView.bottomAnchor | |
| 295 constant:12], | |
| 296 [self.copiedButtonView.bottomAnchor | |
| 297 constraintEqualToAnchor:self.secondaryEffectView.bottomAnchor | |
| 298 constant:-kContentMargin], | |
| 299 | |
| 300 [self.openCopiedURLTitleLabel.centerXAnchor | |
| 301 constraintEqualToAnchor:self.primaryEffectView.centerXAnchor], | |
| 302 [self.openCopiedURLTitleLabel.topAnchor | |
| 303 constraintEqualToAnchor:self.copiedButtonView.topAnchor | |
| 304 constant:kURLButtonMargin], | |
| 305 [self.openCopiedURLTitleLabel.widthAnchor | |
| 306 constraintEqualToAnchor:self.copiedButtonView.widthAnchor | |
| 307 constant:-kContentMargin * 2], | |
| 308 | |
| 309 [self.copiedURLLabel.centerXAnchor | |
| 310 constraintEqualToAnchor:self.primaryEffectView.centerXAnchor], | |
| 311 [self.copiedURLLabel.topAnchor | |
| 312 constraintEqualToAnchor:self.openCopiedURLTitleLabel.bottomAnchor], | |
| 313 [self.copiedURLLabel.widthAnchor | |
| 314 constraintEqualToAnchor:self.openCopiedURLTitleLabel.widthAnchor], | |
| 315 [self.copiedURLLabel.bottomAnchor | |
| 316 constraintEqualToAnchor:self.copiedButtonView.bottomAnchor | |
| 317 constant:-kURLButtonMargin], | |
| 318 ]; | |
| 319 } | |
| 320 | |
| 321 - (void)addTapAction:(SEL)action toView:(UIView*)view { | |
| 58 UIGestureRecognizer* tapRecognizer = | 322 UIGestureRecognizer* tapRecognizer = |
| 59 [[UITapGestureRecognizer alloc] initWithTarget:_target | 323 [[UITapGestureRecognizer alloc] initWithTarget:self.target action:action]; |
| 60 action:@selector(openSearch:)]; | 324 [view addGestureRecognizer:tapRecognizer]; |
| 61 | 325 } |
| 62 [fakebox addGestureRecognizer:tapRecognizer]; | 326 |
| 63 [self addSubview:fakebox]; | 327 - (void)updateCopiedURLUI { |
| 64 | 328 // If the copiedURL section is not visible, hide all the copiedURL section |
| 65 UIView* cursor = [[UIView alloc] initWithFrame:CGRectZero]; | 329 // views and activate the correct constraint set. If it is visible, show the |
| 66 self.cursor = cursor; | 330 // views in function of whether there is or not a copied URL to show. |
| 67 self.cursor.backgroundColor = [UIColor blueColor]; | 331 |
| 68 [fakebox addSubview:self.cursor]; | 332 if (!self.copiedURLVisible) { |
| 69 | 333 self.copiedURLLabel.hidden = YES; |
| 70 [fakebox setTranslatesAutoresizingMaskIntoConstraints:NO]; | 334 self.openCopiedURLTitleLabel.hidden = YES; |
| 71 [self.cursor setTranslatesAutoresizingMaskIntoConstraints:NO]; | 335 self.hairlineView.hidden = YES; |
| 72 [NSLayoutConstraint activateConstraints:@[ | 336 self.copiedButtonView.hidden = YES; |
| 73 [[fakebox leadingAnchor] constraintEqualToAnchor:self.leadingAnchor | 337 [NSLayoutConstraint deactivateConstraints:self.visibleCopiedURLConstraints]; |
| 74 constant:kFakeboxHorizontalPadding], | 338 [NSLayoutConstraint activateConstraints:self.hiddenCopiedURLConstraints]; |
| 75 [[fakebox trailingAnchor] | 339 return; |
| 76 constraintEqualToAnchor:self.trailingAnchor | 340 } |
| 77 constant:-kFakeboxHorizontalPadding], | 341 |
| 78 [[fakebox topAnchor] constraintEqualToAnchor:self.topAnchor | 342 self.copiedURLLabel.hidden = NO; |
| 79 constant:kFakeboxVerticalPadding], | 343 self.openCopiedURLTitleLabel.hidden = NO; |
| 80 [[fakebox heightAnchor] | 344 |
| 81 constraintEqualToConstant:kCursorHeight + 2 * kCursorVerticalPadding], | 345 [NSLayoutConstraint deactivateConstraints:self.hiddenCopiedURLConstraints]; |
| 82 | 346 [NSLayoutConstraint activateConstraints:self.visibleCopiedURLConstraints]; |
| 83 [[self.cursor widthAnchor] constraintEqualToConstant:kCursorWidth], | 347 |
| 84 [[self.cursor leadingAnchor] | 348 if (self.copiedURLString) { |
| 85 constraintEqualToAnchor:fakebox.leadingAnchor | 349 self.copiedButtonView.hidden = NO; |
| 86 constant:kCursorHorizontalPadding], | 350 self.hairlineView.hidden = YES; |
| 87 [[self.cursor heightAnchor] constraintEqualToConstant:kCursorHeight], | 351 self.copiedURLLabel.text = self.copiedURLString; |
| 88 [[self.cursor centerYAnchor] constraintEqualToAnchor:fakebox.centerYAnchor] | 352 self.openCopiedURLTitleLabel.alpha = 1; |
| 89 ]]; | 353 self.openCopiedURLTitleLabel.text = @"Open Copied Link"; |
| 90 | 354 self.copiedURLLabel.alpha = 1; |
| 91 [UIView animateWithDuration:0.3 | 355 return; |
| 92 delay:0.0 | 356 } |
| 93 options:UIViewAnimationOptionRepeat | | 357 |
| 94 UIViewAnimationOptionAutoreverse | 358 self.copiedButtonView.hidden = YES; |
| 95 animations:^{ | 359 self.hairlineView.hidden = NO; |
| 96 self.cursor.alpha = 0.0f; | 360 self.copiedURLLabel.text = @"Links you copy will appear here."; |
| 97 } | 361 self.openCopiedURLTitleLabel.alpha = 0.5; |
| 98 completion:nil]; | 362 self.openCopiedURLTitleLabel.text = @"No Copied Link"; |
| 99 } | 363 self.copiedURLLabel.alpha = 0.5; |
| 100 | 364 } |
| 101 - (void)updateCopiedURL:(NSString*)copiedURL { | |
| 102 self.copiedURL = copiedURL; | |
| 103 self.copiedURLLabel.text = copiedURL; | |
| 104 } | |
| 105 | |
| 106 @end | 365 @end |
| OLD | NEW |