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

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

Issue 2709233003: Add haptic feedback for swipe-to-go-back. (Closed)
Patch Set: File is ARC. Created 3 years, 10 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/browser/ui/side_swipe/side_swipe_navigation_view.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 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/ios/ios_util.h"
11 #include "base/logging.h" 10 #include "base/logging.h"
12 #include "base/mac/objc_property_releaser.h" 11 #include "base/mac/objc_property_releaser.h"
13 #include "base/mac/scoped_nsobject.h" 12 #include "base/mac/scoped_nsobject.h"
14 #include "base/metrics/histogram_macros.h" 13 #include "base/metrics/histogram_macros.h"
15 #import "ios/chrome/browser/ui/browser_view_controller.h" 14 #import "ios/chrome/browser/ui/browser_view_controller.h"
16 #import "ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.h" 15 #import "ios/chrome/browser/ui/overscroll_actions/overscroll_actions_view.h"
17 #include "ios/chrome/browser/ui/rtl_geometry.h" 16 #include "ios/chrome/browser/ui/rtl_geometry.h"
18 #import "ios/chrome/browser/ui/toolbar/toolbar_controller.h" 17 #import "ios/chrome/browser/ui/toolbar/toolbar_controller.h"
19 #import "ios/chrome/browser/ui/toolbar/web_toolbar_controller.h" 18 #import "ios/chrome/browser/ui/toolbar/web_toolbar_controller.h"
19 #include "ios/chrome/browser/ui/uikit_ui_util.h"
20 #import "ios/chrome/browser/ui/voice/voice_search_notification_names.h" 20 #import "ios/chrome/browser/ui/voice/voice_search_notification_names.h"
21 #import "ios/web/public/web_state/crw_web_view_proxy.h" 21 #import "ios/web/public/web_state/crw_web_view_proxy.h"
22 22
23 namespace { 23 namespace {
24 // This enum is used to record the overscroll actions performed by the user on 24 // This enum is used to record the overscroll actions performed by the user on
25 // the histogram named |OverscrollActions|. 25 // the histogram named |OverscrollActions|.
26 enum { 26 enum {
27 // Records each time the user selects the new tab action. 27 // Records each time the user selects the new tab action.
28 OVERSCROLL_ACTION_NEW_TAB, 28 OVERSCROLL_ACTION_NEW_TAB,
29 // Records each time the user selects the refresh action. 29 // Records each time the user selects the refresh action.
(...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 // Not doing so would result in a graphic issue where the scrollview jumps 645 // Not doing so would result in a graphic issue where the scrollview jumps
646 // when scrolling after a change in UI orientation. 646 // when scrolling after a change in UI orientation.
647 [[self scrollView] panGestureRecognizer].enabled = NO; 647 [[self scrollView] panGestureRecognizer].enabled = NO;
648 [[self scrollView] panGestureRecognizer].enabled = YES; 648 [[self scrollView] panGestureRecognizer].enabled = YES;
649 649
650 [self setScrollViewContentInset:UIEdgeInsetsMake(self.initialContentInset, 0, 650 [self setScrollViewContentInset:UIEdgeInsetsMake(self.initialContentInset, 0,
651 0, 0)]; 651 0, 0)];
652 [self clear]; 652 [self clear];
653 } 653 }
654 654
655 // On iOS10 and above, trigger a haptic vibration for the user selecting an
656 // action. This is a no-op for devices that do not support it.
657 - (void)triggerHapticFeedbackForAction {
658 if (base::ios::IsRunningOnIOS10OrLater()) {
659 base::scoped_nsobject<UIImpactFeedbackGenerator> generator(
660 [[UIImpactFeedbackGenerator alloc] init]);
661 [generator impactOccurred];
662 }
663 }
664
665 // On iOS10 and above, trigger a haptic vibration for the change in selection.
666 // This is a no-op for devices that do not support it.
667 - (void)triggerHapticFeedbackForSelectionChange {
668 if (base::ios::IsRunningOnIOS10OrLater()) {
669 base::scoped_nsobject<UISelectionFeedbackGenerator> generator(
670 [[UISelectionFeedbackGenerator alloc] init]);
671 [generator selectionChanged];
672 }
673 }
674
675 - (BOOL)isOverscrollActionEnabled { 655 - (BOOL)isOverscrollActionEnabled {
676 return _overscrollActionLock == 0 && _allowPullingActions && 656 return _overscrollActionLock == 0 && _allowPullingActions &&
677 !_isOverscrollActionsDisabledForLoading; 657 !_isOverscrollActionsDisabledForLoading;
678 } 658 }
679 659
680 - (void)triggerActionIfNeeded { 660 - (void)triggerActionIfNeeded {
681 if ([self isOverscrollActionEnabled]) { 661 if ([self isOverscrollActionEnabled]) {
682 const BOOL isOverscrollStateActionReady = 662 const BOOL isOverscrollStateActionReady =
683 self.overscrollState == OverscrollState::ACTION_READY; 663 self.overscrollState == OverscrollState::ACTION_READY;
684 const BOOL isOverscrollActionNone = 664 const BOOL isOverscrollActionNone =
685 self.overscrollActionView.selectedAction == OverscrollAction::NONE; 665 self.overscrollActionView.selectedAction == OverscrollAction::NONE;
686 666
687 if ((!isOverscrollStateActionReady && _didTransitionToActionReady) || 667 if ((!isOverscrollStateActionReady && _didTransitionToActionReady) ||
688 (isOverscrollStateActionReady && isOverscrollActionNone)) { 668 (isOverscrollStateActionReady && isOverscrollActionNone)) {
689 [self recordMetricForTriggeredAction:OverscrollAction::NONE]; 669 [self recordMetricForTriggeredAction:OverscrollAction::NONE];
690 } else if (isOverscrollStateActionReady && !isOverscrollActionNone) { 670 } else if (isOverscrollStateActionReady && !isOverscrollActionNone) {
691 if (CACurrentMediaTime() - _lastScrollBeginTime >= 671 if (CACurrentMediaTime() - _lastScrollBeginTime >=
692 kMinimumPullDurationToTriggerActionInSeconds) { 672 kMinimumPullDurationToTriggerActionInSeconds) {
693 _performingScrollViewIndependentAnimation = YES; 673 _performingScrollViewIndependentAnimation = YES;
694 [self setScrollViewContentInset:UIEdgeInsetsMake( 674 [self setScrollViewContentInset:UIEdgeInsetsMake(
695 self.initialContentInset, 0, 0, 0)]; 675 self.initialContentInset, 0, 0, 0)];
696 CGPoint contentOffset = [[self scrollView] contentOffset]; 676 CGPoint contentOffset = [[self scrollView] contentOffset];
697 contentOffset.y = -self.initialContentInset; 677 contentOffset.y = -self.initialContentInset;
698 [[self scrollView] setContentOffset:contentOffset animated:YES]; 678 [[self scrollView] setContentOffset:contentOffset animated:YES];
699 [self.overscrollActionView displayActionAnimation]; 679 [self.overscrollActionView displayActionAnimation];
700 dispatch_async(dispatch_get_main_queue(), ^{ 680 dispatch_async(dispatch_get_main_queue(), ^{
701 [self recordMetricForTriggeredAction:self.overscrollActionView 681 [self recordMetricForTriggeredAction:self.overscrollActionView
702 .selectedAction]; 682 .selectedAction];
703 [self triggerHapticFeedbackForAction]; 683 TriggerHapticFeedbackForAction();
704 [self.delegate overscrollActionsController:self 684 [self.delegate overscrollActionsController:self
705 didTriggerAction:self.overscrollActionView 685 didTriggerAction:self.overscrollActionView
706 .selectedAction]; 686 .selectedAction];
707 }); 687 });
708 } 688 }
709 } 689 }
710 } 690 }
711 } 691 }
712 692
713 - (void)setOverscrollState:(OverscrollState)overscrollState { 693 - (void)setOverscrollState:(OverscrollState)overscrollState {
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
910 recordMetricForTriggeredAction:self.overscrollActionView.selectedAction]; 890 recordMetricForTriggeredAction:self.overscrollActionView.selectedAction];
911 891
912 // Reset all pan gesture recognizers. 892 // Reset all pan gesture recognizers.
913 _allowPullingActions = NO; 893 _allowPullingActions = NO;
914 _panGestureRecognizer.enabled = NO; 894 _panGestureRecognizer.enabled = NO;
915 _panGestureRecognizer.enabled = YES; 895 _panGestureRecognizer.enabled = YES;
916 [self scrollView].panGestureRecognizer.enabled = NO; 896 [self scrollView].panGestureRecognizer.enabled = NO;
917 [self scrollView].panGestureRecognizer.enabled = YES; 897 [self scrollView].panGestureRecognizer.enabled = YES;
918 [self startBounceWithInitialVelocity:CGPointZero]; 898 [self startBounceWithInitialVelocity:CGPointZero];
919 899
920 [self triggerHapticFeedbackForAction]; 900 TriggerHapticFeedbackForAction();
921 [self.delegate 901 [self.delegate
922 overscrollActionsController:self 902 overscrollActionsController:self
923 didTriggerAction:self.overscrollActionView.selectedAction]; 903 didTriggerAction:self.overscrollActionView.selectedAction];
924 } 904 }
925 905
926 - (void)overscrollActionsView:(OverscrollActionsView*)view 906 - (void)overscrollActionsView:(OverscrollActionsView*)view
927 selectedActionDidChange:(OverscrollAction)newAction { 907 selectedActionDidChange:(OverscrollAction)newAction {
928 [self triggerHapticFeedbackForSelectionChange]; 908 TriggerHapticFeedbackForSelectionChange();
929 } 909 }
930 910
931 @end 911 @end
OLDNEW
« no previous file with comments | « no previous file | ios/chrome/browser/ui/side_swipe/side_swipe_navigation_view.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698