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

Side by Side Diff: ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.mm

Issue 2611673002: Moves overscroll code out of the ios_internal namespace. (Closed)
Patch Set: 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 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/overscroll_actions/overscroll_actions_controller. h" 5 #import "ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller. h"
6 6
7 #import <QuartzCore/QuartzCore.h> 7 #import <QuartzCore/QuartzCore.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 CGFloat Clamp(CGFloat value, CGFloat min, CGFloat max) { 87 CGFloat Clamp(CGFloat value, CGFloat min, CGFloat max) {
88 DCHECK(min < max); 88 DCHECK(min < max);
89 if (value < min) 89 if (value < min)
90 return min; 90 return min;
91 if (value > max) 91 if (value > max)
92 return max; 92 return max;
93 return value; 93 return value;
94 } 94 }
95 } // namespace 95 } // namespace
96 96
97 namespace ios_internal { 97 NSString* const kOverscrollActionsWillStart = @"OverscrollActionsWillStart";
98 NSString* const kOverscollActionsWillStart = @"OverscollActionsWillStart"; 98 NSString* const kOverscrollActionsDidEnd = @"OverscrollActionsDidStop";
99 NSString* const kOverscollActionsDidEnd = @"OverscollActionsDidStop";
100 } // namespace ios_internal
101 99
102 // This protocol describes the subset of methods used between the 100 // This protocol describes the subset of methods used between the
103 // CRWWebViewScrollViewProxy and the UIWebView. 101 // CRWWebViewScrollViewProxy and the UIWebView.
104 @protocol OverscrollActionsScrollView<NSObject> 102 @protocol OverscrollActionsScrollView<NSObject>
105 103
106 @property(nonatomic, assign) UIEdgeInsets contentInset; 104 @property(nonatomic, assign) UIEdgeInsets contentInset;
107 @property(nonatomic, assign) CGPoint contentOffset; 105 @property(nonatomic, assign) CGPoint contentOffset;
108 @property(nonatomic, assign) UIEdgeInsets scrollIndicatorInsets; 106 @property(nonatomic, assign) UIEdgeInsets scrollIndicatorInsets;
109 @property(nonatomic, readonly) UIPanGestureRecognizer* panGestureRecognizer; 107 @property(nonatomic, readonly) UIPanGestureRecognizer* panGestureRecognizer;
110 @property(nonatomic, readonly) BOOL isZooming; 108 @property(nonatomic, readonly) BOOL isZooming;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 @property(nonatomic, readonly) CGFloat initialContentInset; 174 @property(nonatomic, readonly) CGFloat initialContentInset;
177 // Initial top inset for the header. 175 // Initial top inset for the header.
178 // This property is set from the delegate headerInset and cached on first 176 // This property is set from the delegate headerInset and cached on first
179 // call. The cached value is reset when the webview proxy is set. 177 // call. The cached value is reset when the webview proxy is set.
180 @property(nonatomic, readonly) CGFloat initialHeaderInset; 178 @property(nonatomic, readonly) CGFloat initialHeaderInset;
181 // Initial height of the header view. 179 // Initial height of the header view.
182 // This property is set from the delegate headerHeight and cached on first 180 // This property is set from the delegate headerHeight and cached on first
183 // call. The cached value is reset when the webview proxy is set. 181 // call. The cached value is reset when the webview proxy is set.
184 @property(nonatomic, readonly) CGFloat initialHeaderHeight; 182 @property(nonatomic, readonly) CGFloat initialHeaderHeight;
185 // Redefined to be read-write. 183 // Redefined to be read-write.
186 @property(nonatomic, assign, readwrite) 184 @property(nonatomic, assign, readwrite) OverscrollState overscrollState;
187 ios_internal::OverscrollState overscrollState;
188 // Point where the horizontal gesture started when the state of the 185 // Point where the horizontal gesture started when the state of the
189 // overscroll controller is in OverscrollStateActionReady. 186 // overscroll controller is in OverscrollStateActionReady.
190 @property(nonatomic, assign) CGPoint panPointScreenOrigin; 187 @property(nonatomic, assign) CGPoint panPointScreenOrigin;
191 // Pan gesture recognizer used to track horizontal touches. 188 // Pan gesture recognizer used to track horizontal touches.
192 @property(nonatomic, retain) UIPanGestureRecognizer* panGestureRecognizer; 189 @property(nonatomic, retain) UIPanGestureRecognizer* panGestureRecognizer;
193 190
194 // Registers notifications to lock the overscroll actions on certain UI states. 191 // Registers notifications to lock the overscroll actions on certain UI states.
195 - (void)registerNotifications; 192 - (void)registerNotifications;
196 // Setup/tearDown methods are used to register values when the delegate is set. 193 // Setup/tearDown methods are used to register values when the delegate is set.
197 - (void)tearDown; 194 - (void)tearDown;
198 - (void)setup; 195 - (void)setup;
199 // Resets scroll view's top content inset to |self.initialContentInset|. 196 // Resets scroll view's top content inset to |self.initialContentInset|.
200 - (void)resetScrollViewTopContentInset; 197 - (void)resetScrollViewTopContentInset;
201 // Access the headerView from the delegate. 198 // Access the headerView from the delegate.
202 - (UIView<RelaxedBoundsConstraintsHitTestSupport>*)headerView; 199 - (UIView<RelaxedBoundsConstraintsHitTestSupport>*)headerView;
203 // Locking/unlocking methods used to disable/enable the overscroll actions 200 // Locking/unlocking methods used to disable/enable the overscroll actions
204 // with a reference count. 201 // with a reference count.
205 - (void)incrementOverscrollActionLockForNotification: 202 - (void)incrementOverscrollActionLockForNotification:
206 (NSNotification*)notification; 203 (NSNotification*)notification;
207 - (void)decrementOverscrollActionLockForNotification: 204 - (void)decrementOverscrollActionLockForNotification:
208 (NSNotification*)notification; 205 (NSNotification*)notification;
209 // Indicates whether the overscroll action is allowed. 206 // Indicates whether the overscroll action is allowed.
210 - (BOOL)isOverscrollActionEnabled; 207 - (BOOL)isOverscrollActionEnabled;
211 // Triggers a call to delegate if an action has been triggered. 208 // Triggers a call to delegate if an action has been triggered.
212 - (void)triggerActionIfNeeded; 209 - (void)triggerActionIfNeeded;
213 // Performs work based on overscroll action state changes. 210 // Performs work based on overscroll action state changes.
214 - (void)onOverscrollStateChangeWithPreviousState: 211 - (void)onOverscrollStateChangeWithPreviousState:
215 (ios_internal::OverscrollState)previousOverscrollState; 212 (OverscrollState)previousOverscrollState;
216 // Disables all interactions on the webview except pan. 213 // Disables all interactions on the webview except pan.
217 - (void)setWebViewInteractionEnabled:(BOOL)enabled; 214 - (void)setWebViewInteractionEnabled:(BOOL)enabled;
218 // Bounce dynamic animations methods. 215 // Bounce dynamic animations methods.
219 // Starts the bounce animation with an initial velocity. 216 // Starts the bounce animation with an initial velocity.
220 - (void)startBounceWithInitialVelocity:(CGPoint)velocity; 217 - (void)startBounceWithInitialVelocity:(CGPoint)velocity;
221 // Stops bounce animation. 218 // Stops bounce animation.
222 - (void)stopBounce; 219 - (void)stopBounce;
223 // Called from the display link to update the bounce dynamic animation. 220 // Called from the display link to update the bounce dynamic animation.
224 - (void)updateBounce; 221 - (void)updateBounce;
225 // Applies bounce state to the scroll view. 222 // Applies bounce state to the scroll view.
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 [self tearDown]; 284 [self tearDown];
288 [[NSNotificationCenter defaultCenter] removeObserver:self]; 285 [[NSNotificationCenter defaultCenter] removeObserver:self];
289 [self setWebViewInteractionEnabled:YES]; 286 [self setWebViewInteractionEnabled:YES];
290 _delegate = nil; 287 _delegate = nil;
291 _webViewProxy.reset(); 288 _webViewProxy.reset();
292 [_webViewScrollViewProxy removeObserver:self]; 289 [_webViewScrollViewProxy removeObserver:self];
293 _webViewScrollViewProxy.reset(); 290 _webViewScrollViewProxy.reset();
294 } 291 }
295 292
296 - (void)clear { 293 - (void)clear {
297 self.overscrollState = ios_internal::OverscrollState::NO_PULL_STARTED; 294 self.overscrollState = OverscrollState::NO_PULL_STARTED;
298 } 295 }
299 296
300 - (void)enableOverscrollActions { 297 - (void)enableOverscrollActions {
301 _isOverscrollActionsDisabledForLoading = NO; 298 _isOverscrollActionsDisabledForLoading = NO;
302 [self setup]; 299 [self setup];
303 } 300 }
304 301
305 - (void)disableOverscrollActions { 302 - (void)disableOverscrollActions {
306 _isOverscrollActionsDisabledForLoading = YES; 303 _isOverscrollActionsDisabledForLoading = YES;
307 [self tearDown]; 304 [self tearDown];
308 } 305 }
309 306
310 - (void)setStyle:(ios_internal::OverscrollStyle)style { 307 - (void)setStyle:(OverscrollStyle)style {
311 [self.overscrollActionView setStyle:style]; 308 [self.overscrollActionView setStyle:style];
312 } 309 }
313 310
314 #pragma mark - webViewScrollView and UIScrollView delegates implementations 311 #pragma mark - webViewScrollView and UIScrollView delegates implementations
315 312
316 - (void)scrollViewDidScroll { 313 - (void)scrollViewDidScroll {
317 if (!_forceStateUpdate && (![self isOverscrollActionEnabled] || 314 if (!_forceStateUpdate && (![self isOverscrollActionEnabled] ||
318 _performingScrollViewIndependentAnimation)) 315 _performingScrollViewIndependentAnimation))
319 return; 316 return;
320 317
321 const UIEdgeInsets insets = 318 const UIEdgeInsets insets =
322 UIEdgeInsetsMake(-[self scrollView].contentOffset.y, 0, 0, 0); 319 UIEdgeInsetsMake(-[self scrollView].contentOffset.y, 0, 0, 0);
323 // Start pulling (on top). 320 // Start pulling (on top).
324 CGFloat contentOffsetFromTheTop = [self scrollView].contentOffset.y; 321 CGFloat contentOffsetFromTheTop = [self scrollView].contentOffset.y;
325 if (![_webViewProxy shouldUseInsetForTopPadding]) { 322 if (![_webViewProxy shouldUseInsetForTopPadding]) {
326 // Content offset is shifted for WKWebView when the web view's 323 // Content offset is shifted for WKWebView when the web view's
327 // |shouldUseInsetForTopPadding| is NO, to workaround bug with 324 // |shouldUseInsetForTopPadding| is NO, to workaround bug with
328 // UIScollView.contentInset (rdar://23584409). 325 // UIScollView.contentInset (rdar://23584409).
329 contentOffsetFromTheTop -= [_webViewProxy topContentPadding]; 326 contentOffsetFromTheTop -= [_webViewProxy topContentPadding];
330 } 327 }
331 CGFloat contentOffsetFromExpandedHeader = 328 CGFloat contentOffsetFromExpandedHeader =
332 contentOffsetFromTheTop + self.initialHeaderInset; 329 contentOffsetFromTheTop + self.initialHeaderInset;
333 if (contentOffsetFromExpandedHeader >= 0) { 330 if (contentOffsetFromExpandedHeader >= 0) {
334 // Record initial content offset and dispatch delegate on state change. 331 // Record initial content offset and dispatch delegate on state change.
335 self.overscrollState = ios_internal::OverscrollState::NO_PULL_STARTED; 332 self.overscrollState = OverscrollState::NO_PULL_STARTED;
336 } else { 333 } else {
337 if (contentOffsetFromExpandedHeader < -kHeaderMaxExpansionThreshold) { 334 if (contentOffsetFromExpandedHeader < -kHeaderMaxExpansionThreshold) {
338 self.overscrollState = ios_internal::OverscrollState::ACTION_READY; 335 self.overscrollState = OverscrollState::ACTION_READY;
339 [self scrollView].scrollIndicatorInsets = insets; 336 [self scrollView].scrollIndicatorInsets = insets;
340 } else { 337 } else {
341 // Set the contentInset to remove the bounce that would fight with drag. 338 // Set the contentInset to remove the bounce that would fight with drag.
342 [self setScrollViewContentInset:insets]; 339 [self setScrollViewContentInset:insets];
343 [self scrollView].scrollIndicatorInsets = insets; 340 [self scrollView].scrollIndicatorInsets = insets;
344 self.overscrollState = ios_internal::OverscrollState::STARTED_PULLING; 341 self.overscrollState = OverscrollState::STARTED_PULLING;
345 } 342 }
346 [self updateWithVerticalOffset:-contentOffsetFromExpandedHeader]; 343 [self updateWithVerticalOffset:-contentOffsetFromExpandedHeader];
347 } 344 }
348 } 345 }
349 346
350 - (void)scrollViewWillBeginDragging { 347 - (void)scrollViewWillBeginDragging {
351 [self stopBounce]; 348 [self stopBounce];
352 _allowPullingActions = NO; 349 _allowPullingActions = NO;
353 _didTransitionToActionReady = NO; 350 _didTransitionToActionReady = NO;
354 [self.overscrollActionView pullStarted]; 351 [self.overscrollActionView pullStarted];
355 if (!_performingScrollViewIndependentAnimation) 352 if (!_performingScrollViewIndependentAnimation)
356 _allowPullingActions = [self isOverscrollActionsAllowed]; 353 _allowPullingActions = [self isOverscrollActionsAllowed];
357 _lastScrollBeginTime = CACurrentMediaTime(); 354 _lastScrollBeginTime = CACurrentMediaTime();
358 } 355 }
359 356
360 - (BOOL)isOverscrollActionsAllowed { 357 - (BOOL)isOverscrollActionsAllowed {
361 const BOOL isZooming = [[self scrollView] isZooming]; 358 const BOOL isZooming = [[self scrollView] isZooming];
362 // Check that the scrollview is scrolled to top. 359 // Check that the scrollview is scrolled to top.
363 const BOOL isScrolledToTop = fabs([[self scrollView] contentOffset].y + 360 const BOOL isScrolledToTop = fabs([[self scrollView] contentOffset].y +
364 [[self scrollView] contentInset].top) <= 361 [[self scrollView] contentInset].top) <=
365 kScrolledToTopToleranceInPoint; 362 kScrolledToTopToleranceInPoint;
366 // Check that the user is not quickly scrolling the view repeatedly. 363 // Check that the user is not quickly scrolling the view repeatedly.
367 const BOOL isMinimumTimeBetweenScrollRespected = 364 const BOOL isMinimumTimeBetweenScrollRespected =
368 (CACurrentMediaTime() - _lastScrollBeginTime) >= 365 (CACurrentMediaTime() - _lastScrollBeginTime) >=
369 kMinimumDurationBetweenScrollingInSeconds; 366 kMinimumDurationBetweenScrollingInSeconds;
370 // Finally check that the delegate allow overscroll actions. 367 // Finally check that the delegate allow overscroll actions.
371 const BOOL delegateAllowOverscrollActions = 368 const BOOL delegateAllowOverscrollActions =
372 [self.delegate shouldAllowOverscrollActions]; 369 [self.delegate shouldAllowOverscrollActions];
373 const BOOL isCurrentlyProcessingOverscroll = 370 const BOOL isCurrentlyProcessingOverscroll =
374 self.overscrollState != ios_internal::OverscrollState::NO_PULL_STARTED; 371 self.overscrollState != OverscrollState::NO_PULL_STARTED;
375 return isCurrentlyProcessingOverscroll || 372 return isCurrentlyProcessingOverscroll ||
376 (isScrolledToTop && isMinimumTimeBetweenScrollRespected && 373 (isScrolledToTop && isMinimumTimeBetweenScrollRespected &&
377 delegateAllowOverscrollActions && !isZooming); 374 delegateAllowOverscrollActions && !isZooming);
378 } 375 }
379 376
380 - (void)scrollViewDidEndDraggingWillDecelerate:(BOOL)decelerate 377 - (void)scrollViewDidEndDraggingWillDecelerate:(BOOL)decelerate
381 contentOffset:(CGPoint)contentOffset { 378 contentOffset:(CGPoint)contentOffset {
382 // Content is now hidden behind toolbar, make sure that contentInset is 379 // Content is now hidden behind toolbar, make sure that contentInset is
383 // restored to initial value. 380 // restored to initial value.
384 if (contentOffset.y >= 0 || 381 if (contentOffset.y >= 0 ||
385 self.overscrollState == ios_internal::OverscrollState::NO_PULL_STARTED) { 382 self.overscrollState == OverscrollState::NO_PULL_STARTED) {
386 [self resetScrollViewTopContentInset]; 383 [self resetScrollViewTopContentInset];
387 } 384 }
388 385
389 [self triggerActionIfNeeded]; 386 [self triggerActionIfNeeded];
390 _allowPullingActions = NO; 387 _allowPullingActions = NO;
391 } 388 }
392 389
393 - (void)scrollViewWillEndDraggingWithVelocity:(CGPoint)velocity 390 - (void)scrollViewWillEndDraggingWithVelocity:(CGPoint)velocity
394 targetContentOffset: 391 targetContentOffset:
395 (inout CGPoint*)targetContentOffset { 392 (inout CGPoint*)targetContentOffset {
396 if (![self isOverscrollActionEnabled]) 393 if (![self isOverscrollActionEnabled])
397 return; 394 return;
398 395
399 if (self.overscrollState != ios_internal::OverscrollState::NO_PULL_STARTED) { 396 if (self.overscrollState != OverscrollState::NO_PULL_STARTED) {
400 *targetContentOffset = [[self scrollView] contentOffset]; 397 *targetContentOffset = [[self scrollView] contentOffset];
401 [self startBounceWithInitialVelocity:velocity]; 398 [self startBounceWithInitialVelocity:velocity];
402 } 399 }
403 } 400 }
404 401
405 - (void)webViewScrollViewProxyDidSetScrollView: 402 - (void)webViewScrollViewProxyDidSetScrollView:
406 (CRWWebViewScrollViewProxy*)webViewScrollViewProxy { 403 (CRWWebViewScrollViewProxy*)webViewScrollViewProxy {
407 [self setup]; 404 [self setup];
408 } 405 }
409 406
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 #pragma mark - Pan gesture recognizer handling 466 #pragma mark - Pan gesture recognizer handling
470 467
471 - (void)panGesture:(UIPanGestureRecognizer*)gesture { 468 - (void)panGesture:(UIPanGestureRecognizer*)gesture {
472 if (gesture.state == UIGestureRecognizerStateBegan) { 469 if (gesture.state == UIGestureRecognizerStateBegan) {
473 [self setWebViewInteractionEnabled:NO]; 470 [self setWebViewInteractionEnabled:NO];
474 } else if (gesture.state == UIGestureRecognizerStateEnded || 471 } else if (gesture.state == UIGestureRecognizerStateEnded ||
475 gesture.state == UIGestureRecognizerStateCancelled) { 472 gesture.state == UIGestureRecognizerStateCancelled) {
476 [self setWebViewInteractionEnabled:YES]; 473 [self setWebViewInteractionEnabled:YES];
477 } 474 }
478 const CGPoint panPointScreen = [gesture locationInView:nil]; 475 const CGPoint panPointScreen = [gesture locationInView:nil];
479 if (self.overscrollState == ios_internal::OverscrollState::ACTION_READY) { 476 if (self.overscrollState == OverscrollState::ACTION_READY) {
480 const CGFloat direction = UseRTLLayout() ? -1 : 1; 477 const CGFloat direction = UseRTLLayout() ? -1 : 1;
481 const CGFloat xOffset = direction * 478 const CGFloat xOffset = direction *
482 (panPointScreen.x - self.panPointScreenOrigin.x) / 479 (panPointScreen.x - self.panPointScreenOrigin.x) /
483 kHorizontalPanDistance; 480 kHorizontalPanDistance;
484 481
485 [self.overscrollActionView updateWithHorizontalOffset:xOffset]; 482 [self.overscrollActionView updateWithHorizontalOffset:xOffset];
486 } 483 }
487 } 484 }
488 485
489 - (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer 486 - (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer
(...skipping 18 matching lines...) Expand all
508 505
509 - (void)webControllerWillClose:(CRWWebController*)webController { 506 - (void)webControllerWillClose:(CRWWebController*)webController {
510 [self disableOverscrollActions]; 507 [self disableOverscrollActions];
511 [_webViewScrollViewProxy removeObserver:self]; 508 [_webViewScrollViewProxy removeObserver:self];
512 _webViewScrollViewProxy.reset(); 509 _webViewScrollViewProxy.reset();
513 [webController removeObserver:self]; 510 [webController removeObserver:self];
514 } 511 }
515 512
516 #pragma mark - Private 513 #pragma mark - Private
517 514
518 - (void)recordMetricForTriggeredAction:(ios_internal::OverscrollAction)action { 515 - (void)recordMetricForTriggeredAction:(OverscrollAction)action {
519 switch (action) { 516 switch (action) {
520 case ios_internal::OverscrollAction::NONE: 517 case OverscrollAction::NONE:
521 UMA_HISTOGRAM_ENUMERATION(kOverscrollActionsHistogram, 518 UMA_HISTOGRAM_ENUMERATION(kOverscrollActionsHistogram,
522 OVERSCROLL_ACTION_CANCELED, 519 OVERSCROLL_ACTION_CANCELED,
523 OVERSCROLL_ACTION_COUNT); 520 OVERSCROLL_ACTION_COUNT);
524 break; 521 break;
525 case ios_internal::OverscrollAction::NEW_TAB: 522 case OverscrollAction::NEW_TAB:
526 UMA_HISTOGRAM_ENUMERATION(kOverscrollActionsHistogram, 523 UMA_HISTOGRAM_ENUMERATION(kOverscrollActionsHistogram,
527 OVERSCROLL_ACTION_NEW_TAB, 524 OVERSCROLL_ACTION_NEW_TAB,
528 OVERSCROLL_ACTION_COUNT); 525 OVERSCROLL_ACTION_COUNT);
529 break; 526 break;
530 case ios_internal::OverscrollAction::REFRESH: 527 case OverscrollAction::REFRESH:
531 UMA_HISTOGRAM_ENUMERATION(kOverscrollActionsHistogram, 528 UMA_HISTOGRAM_ENUMERATION(kOverscrollActionsHistogram,
532 OVERSCROLL_ACTION_REFRESH, 529 OVERSCROLL_ACTION_REFRESH,
533 OVERSCROLL_ACTION_COUNT); 530 OVERSCROLL_ACTION_COUNT);
534 break; 531 break;
535 case ios_internal::OverscrollAction::CLOSE_TAB: 532 case OverscrollAction::CLOSE_TAB:
536 UMA_HISTOGRAM_ENUMERATION(kOverscrollActionsHistogram, 533 UMA_HISTOGRAM_ENUMERATION(kOverscrollActionsHistogram,
537 OVERSCROLL_ACTION_CLOSE_TAB, 534 OVERSCROLL_ACTION_CLOSE_TAB,
538 OVERSCROLL_ACTION_COUNT); 535 OVERSCROLL_ACTION_COUNT);
539 break; 536 break;
540 } 537 }
541 } 538 }
542 539
543 - (void)registerNotifications { 540 - (void)registerNotifications {
544 NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; 541 NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
545 for (NSString* counterpartNotificationName in _lockNotificationsCounterparts 542 for (NSString* counterpartNotificationName in _lockNotificationsCounterparts
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 NSString* counterpartName = 609 NSString* counterpartName =
613 [_lockNotificationsCounterparts objectForKey:notif.name]; 610 [_lockNotificationsCounterparts objectForKey:notif.name];
614 if ([_lockIncrementNotifications containsObject:counterpartName]) { 611 if ([_lockIncrementNotifications containsObject:counterpartName]) {
615 [_lockIncrementNotifications removeObject:counterpartName]; 612 [_lockIncrementNotifications removeObject:counterpartName];
616 if (_overscrollActionLock > 0) 613 if (_overscrollActionLock > 0)
617 --_overscrollActionLock; 614 --_overscrollActionLock;
618 } 615 }
619 } 616 }
620 617
621 - (void)deviceOrientationDidChange { 618 - (void)deviceOrientationDidChange {
622 if (self.overscrollState == ios_internal::OverscrollState::NO_PULL_STARTED && 619 if (self.overscrollState == OverscrollState::NO_PULL_STARTED &&
623 !_performingScrollViewIndependentAnimation) 620 !_performingScrollViewIndependentAnimation)
624 return; 621 return;
625 622
626 const UIDeviceOrientation deviceOrientation = 623 const UIDeviceOrientation deviceOrientation =
627 [[UIDevice currentDevice] orientation]; 624 [[UIDevice currentDevice] orientation];
628 if (deviceOrientation != UIDeviceOrientationLandscapeRight && 625 if (deviceOrientation != UIDeviceOrientationLandscapeRight &&
629 deviceOrientation != UIDeviceOrientationLandscapeLeft && 626 deviceOrientation != UIDeviceOrientationLandscapeLeft &&
630 deviceOrientation != UIDeviceOrientationPortrait) { 627 deviceOrientation != UIDeviceOrientationPortrait) {
631 return; 628 return;
632 } 629 }
(...skipping 11 matching lines...) Expand all
644 } 641 }
645 642
646 - (BOOL)isOverscrollActionEnabled { 643 - (BOOL)isOverscrollActionEnabled {
647 return _overscrollActionLock == 0 && _allowPullingActions && 644 return _overscrollActionLock == 0 && _allowPullingActions &&
648 !_isOverscrollActionsDisabledForLoading; 645 !_isOverscrollActionsDisabledForLoading;
649 } 646 }
650 647
651 - (void)triggerActionIfNeeded { 648 - (void)triggerActionIfNeeded {
652 if ([self isOverscrollActionEnabled]) { 649 if ([self isOverscrollActionEnabled]) {
653 const BOOL isOverscrollStateActionReady = 650 const BOOL isOverscrollStateActionReady =
654 self.overscrollState == ios_internal::OverscrollState::ACTION_READY; 651 self.overscrollState == OverscrollState::ACTION_READY;
655 const BOOL isOverscrollActionNone = 652 const BOOL isOverscrollActionNone =
656 self.overscrollActionView.selectedAction == 653 self.overscrollActionView.selectedAction == OverscrollAction::NONE;
657 ios_internal::OverscrollAction::NONE;
658 654
659 if ((!isOverscrollStateActionReady && _didTransitionToActionReady) || 655 if ((!isOverscrollStateActionReady && _didTransitionToActionReady) ||
660 (isOverscrollStateActionReady && isOverscrollActionNone)) { 656 (isOverscrollStateActionReady && isOverscrollActionNone)) {
661 [self 657 [self recordMetricForTriggeredAction:OverscrollAction::NONE];
662 recordMetricForTriggeredAction:ios_internal::OverscrollAction::NONE];
663 } else if (isOverscrollStateActionReady && !isOverscrollActionNone) { 658 } else if (isOverscrollStateActionReady && !isOverscrollActionNone) {
664 if (CACurrentMediaTime() - _lastScrollBeginTime >= 659 if (CACurrentMediaTime() - _lastScrollBeginTime >=
665 kMinimumPullDurationToTriggerActionInSeconds) { 660 kMinimumPullDurationToTriggerActionInSeconds) {
666 _performingScrollViewIndependentAnimation = YES; 661 _performingScrollViewIndependentAnimation = YES;
667 [self setScrollViewContentInset:UIEdgeInsetsMake( 662 [self setScrollViewContentInset:UIEdgeInsetsMake(
668 self.initialContentInset, 0, 0, 0)]; 663 self.initialContentInset, 0, 0, 0)];
669 CGPoint contentOffset = [[self scrollView] contentOffset]; 664 CGPoint contentOffset = [[self scrollView] contentOffset];
670 contentOffset.y = -self.initialContentInset; 665 contentOffset.y = -self.initialContentInset;
671 [[self scrollView] setContentOffset:contentOffset animated:YES]; 666 [[self scrollView] setContentOffset:contentOffset animated:YES];
672 [self.overscrollActionView displayActionAnimation]; 667 [self.overscrollActionView displayActionAnimation];
673 dispatch_async(dispatch_get_main_queue(), ^{ 668 dispatch_async(dispatch_get_main_queue(), ^{
674 [self recordMetricForTriggeredAction:self.overscrollActionView 669 [self recordMetricForTriggeredAction:self.overscrollActionView
675 .selectedAction]; 670 .selectedAction];
676 [self.delegate overscrollActionsController:self 671 [self.delegate overscrollActionsController:self
677 didTriggerAction:self.overscrollActionView 672 didTriggerAction:self.overscrollActionView
678 .selectedAction]; 673 .selectedAction];
679 }); 674 });
680 } 675 }
681 } 676 }
682 } 677 }
683 } 678 }
684 679
685 - (void)setOverscrollState:(ios_internal::OverscrollState)overscrollState { 680 - (void)setOverscrollState:(OverscrollState)overscrollState {
686 if (_overscrollState != overscrollState) { 681 if (_overscrollState != overscrollState) {
687 const ios_internal::OverscrollState previousState = _overscrollState; 682 const OverscrollState previousState = _overscrollState;
688 _overscrollState = overscrollState; 683 _overscrollState = overscrollState;
689 [self onOverscrollStateChangeWithPreviousState:previousState]; 684 [self onOverscrollStateChangeWithPreviousState:previousState];
690 } 685 }
691 } 686 }
692 687
693 - (void)onOverscrollStateChangeWithPreviousState: 688 - (void)onOverscrollStateChangeWithPreviousState:
694 (ios_internal::OverscrollState)previousOverscrollState { 689 (OverscrollState)previousOverscrollState {
695 [UIView beginAnimations:@"backgroundColor" context:NULL]; 690 [UIView beginAnimations:@"backgroundColor" context:NULL];
696 switch (self.overscrollState) { 691 switch (self.overscrollState) {
697 case ios_internal::OverscrollState::NO_PULL_STARTED: { 692 case OverscrollState::NO_PULL_STARTED: {
698 UIView<RelaxedBoundsConstraintsHitTestSupport>* headerView = 693 UIView<RelaxedBoundsConstraintsHitTestSupport>* headerView =
699 [self headerView]; 694 [self headerView];
700 if ([headerView 695 if ([headerView
701 respondsToSelector:@selector(setHitTestBoundsContraintRelaxed:)]) 696 respondsToSelector:@selector(setHitTestBoundsContraintRelaxed:)])
702 [headerView setHitTestBoundsContraintRelaxed:NO]; 697 [headerView setHitTestBoundsContraintRelaxed:NO];
703 [self.overscrollActionView removeFromSuperview]; 698 [self.overscrollActionView removeFromSuperview];
704 SetViewFrameHeight( 699 SetViewFrameHeight(
705 self.overscrollActionView, 700 self.overscrollActionView,
706 self.initialContentInset + 701 self.initialContentInset +
707 [UIApplication sharedApplication].statusBarFrame.size.height); 702 [UIApplication sharedApplication].statusBarFrame.size.height);
708 self.panPointScreenOrigin = CGPointZero; 703 self.panPointScreenOrigin = CGPointZero;
709 [[NSNotificationCenter defaultCenter] 704 [[NSNotificationCenter defaultCenter]
710 postNotificationName:ios_internal::kOverscollActionsDidEnd 705 postNotificationName:kOverscrollActionsDidEnd
711 object:self]; 706 object:self];
712 } break; 707 } break;
713 case ios_internal::OverscrollState::STARTED_PULLING: { 708 case OverscrollState::STARTED_PULLING: {
714 if (!self.overscrollActionView.superview) { 709 if (!self.overscrollActionView.superview) {
715 if (previousOverscrollState == 710 if (previousOverscrollState == OverscrollState::NO_PULL_STARTED) {
716 ios_internal::OverscrollState::NO_PULL_STARTED) {
717 UIView* view = [self.delegate toolbarSnapshotView]; 711 UIView* view = [self.delegate toolbarSnapshotView];
718 [self.overscrollActionView addSnapshotView:view]; 712 [self.overscrollActionView addSnapshotView:view];
719 [[NSNotificationCenter defaultCenter] 713 [[NSNotificationCenter defaultCenter]
720 postNotificationName:ios_internal::kOverscollActionsWillStart 714 postNotificationName:kOverscrollActionsWillStart
721 object:self]; 715 object:self];
722 } 716 }
723 [CATransaction begin]; 717 [CATransaction begin];
724 [CATransaction setDisableActions:YES]; 718 [CATransaction setDisableActions:YES];
725 self.overscrollActionView.backgroundView.alpha = 1; 719 self.overscrollActionView.backgroundView.alpha = 1;
726 [self.overscrollActionView updateWithVerticalOffset:0]; 720 [self.overscrollActionView updateWithVerticalOffset:0];
727 [self.overscrollActionView updateWithHorizontalOffset:0]; 721 [self.overscrollActionView updateWithHorizontalOffset:0];
728 self.overscrollActionView.frame = [self headerView].bounds; 722 self.overscrollActionView.frame = [self headerView].bounds;
729 DCHECK([self headerView]); 723 DCHECK([self headerView]);
730 UIView<RelaxedBoundsConstraintsHitTestSupport>* headerView = 724 UIView<RelaxedBoundsConstraintsHitTestSupport>* headerView =
731 [self headerView]; 725 [self headerView];
732 if ([headerView 726 if ([headerView
733 respondsToSelector:@selector( 727 respondsToSelector:@selector(
734 setHitTestBoundsContraintRelaxed:)]) 728 setHitTestBoundsContraintRelaxed:)])
735 [headerView setHitTestBoundsContraintRelaxed:YES]; 729 [headerView setHitTestBoundsContraintRelaxed:YES];
736 [headerView addSubview:self.overscrollActionView]; 730 [headerView addSubview:self.overscrollActionView];
737 [CATransaction commit]; 731 [CATransaction commit];
738 } 732 }
739 } break; 733 } break;
740 case ios_internal::OverscrollState::ACTION_READY: { 734 case OverscrollState::ACTION_READY: {
741 _didTransitionToActionReady = YES; 735 _didTransitionToActionReady = YES;
742 if (CGPointEqualToPoint(self.panPointScreenOrigin, CGPointZero)) { 736 if (CGPointEqualToPoint(self.panPointScreenOrigin, CGPointZero)) {
743 CGPoint panPointScreen = [self.panGestureRecognizer locationInView:nil]; 737 CGPoint panPointScreen = [self.panGestureRecognizer locationInView:nil];
744 self.panPointScreenOrigin = panPointScreen; 738 self.panPointScreenOrigin = panPointScreen;
745 } 739 }
746 } break; 740 } break;
747 } 741 }
748 [UIView commitAnimations]; 742 [UIView commitAnimations];
749 } 743 }
750 744
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
807 #pragma mark - Bounce dynamic 801 #pragma mark - Bounce dynamic
808 802
809 - (void)startBounceWithInitialVelocity:(CGPoint)velocity { 803 - (void)startBounceWithInitialVelocity:(CGPoint)velocity {
810 [self stopBounce]; 804 [self stopBounce];
811 CADisplayLink* dpLink = 805 CADisplayLink* dpLink =
812 [CADisplayLink displayLinkWithTarget:self 806 [CADisplayLink displayLinkWithTarget:self
813 selector:@selector(updateBounce)]; 807 selector:@selector(updateBounce)];
814 [dpLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; 808 [dpLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
815 _dpLink = dpLink; 809 _dpLink = dpLink;
816 memset(&_bounceState, 0, sizeof(_bounceState)); 810 memset(&_bounceState, 0, sizeof(_bounceState));
817 if (self.overscrollState == ios_internal::OverscrollState::ACTION_READY) { 811 if (self.overscrollState == OverscrollState::ACTION_READY) {
818 const UIEdgeInsets insets = UIEdgeInsetsMake( 812 const UIEdgeInsets insets = UIEdgeInsetsMake(
819 -[self scrollView].contentOffset.y + self.initialContentInset, 0, 0, 0); 813 -[self scrollView].contentOffset.y + self.initialContentInset, 0, 0, 0);
820 [self setScrollViewContentInset:insets]; 814 [self setScrollViewContentInset:insets];
821 [[self scrollView] setScrollIndicatorInsets:insets]; 815 [[self scrollView] setScrollIndicatorInsets:insets];
822 } 816 }
823 _bounceState.yInset = [self scrollView].contentInset.top; 817 _bounceState.yInset = [self scrollView].contentInset.top;
824 _bounceState.initialYInset = _bounceState.yInset; 818 _bounceState.initialYInset = _bounceState.yInset;
825 _bounceState.headerInset = self.initialContentInset; 819 _bounceState.headerInset = self.initialContentInset;
826 _bounceState.time = CACurrentMediaTime(); 820 _bounceState.time = CACurrentMediaTime();
827 _bounceState.velocityInset = -velocity.y * 1000.0; 821 _bounceState.velocityInset = -velocity.y * 1000.0;
828 } 822 }
829 823
830 - (void)stopBounce { 824 - (void)stopBounce {
831 [_dpLink invalidate]; 825 [_dpLink invalidate];
832 _dpLink = nil; 826 _dpLink = nil;
833 if (_performingScrollViewIndependentAnimation) { 827 if (_performingScrollViewIndependentAnimation) {
834 self.overscrollState = ios_internal::OverscrollState::NO_PULL_STARTED; 828 self.overscrollState = OverscrollState::NO_PULL_STARTED;
835 _performingScrollViewIndependentAnimation = NO; 829 _performingScrollViewIndependentAnimation = NO;
836 } 830 }
837 } 831 }
838 832
839 - (void)updateBounce { 833 - (void)updateBounce {
840 const double time = CACurrentMediaTime(); 834 const double time = CACurrentMediaTime();
841 const double dt = time - _bounceState.time; 835 const double dt = time - _bounceState.time;
842 CGFloat force = -_bounceState.yInset * kSpringTightness; 836 CGFloat force = -_bounceState.yInset * kSpringTightness;
843 if (_bounceState.yInset > _bounceState.headerInset) 837 if (_bounceState.yInset > _bounceState.headerInset)
844 force -= _bounceState.velocityInset * kSpringDampiness; 838 force -= _bounceState.velocityInset * kSpringDampiness;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
879 _panGestureRecognizer.enabled = YES; 873 _panGestureRecognizer.enabled = YES;
880 [self scrollView].panGestureRecognizer.enabled = NO; 874 [self scrollView].panGestureRecognizer.enabled = NO;
881 [self scrollView].panGestureRecognizer.enabled = YES; 875 [self scrollView].panGestureRecognizer.enabled = YES;
882 [self startBounceWithInitialVelocity:CGPointZero]; 876 [self startBounceWithInitialVelocity:CGPointZero];
883 [self.delegate 877 [self.delegate
884 overscrollActionsController:self 878 overscrollActionsController:self
885 didTriggerAction:self.overscrollActionView.selectedAction]; 879 didTriggerAction:self.overscrollActionView.selectedAction];
886 } 880 }
887 881
888 @end 882 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698