From 29c459fe60718f7f89ca55cc209486274cd24835 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Mon, 30 Jul 2018 17:46:34 -0600 Subject: [PATCH] Haptic feedback when changing menu action selection // FREEBIE --- Signal.xcodeproj/project.pbxproj | 4 ++ Signal/src/UserInterface/HapticFeedback.swift | 51 +++++++++++++++++++ .../MenuActionsViewController.swift | 11 +++- 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 Signal/src/UserInterface/HapticFeedback.swift diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index 58a36d5e8..f302588cc 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -414,6 +414,7 @@ 45FBC5C81DF8575700E9B410 /* CallKitCallManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45FBC59A1DF8575700E9B410 /* CallKitCallManager.swift */; }; 45FBC5D11DF8592E00E9B410 /* SignalCall.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45FBC5D01DF8592E00E9B410 /* SignalCall.swift */; }; 4AC4EA13C8A444455DAB351F /* Pods_SignalMessaging.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 264242150E87D10A357DB07B /* Pods_SignalMessaging.framework */; }; + 4C090A1B210FD9C7001FD7F9 /* HapticFeedback.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C090A1A210FD9C7001FD7F9 /* HapticFeedback.swift */; }; 4C11AA5020FD59C700351FBD /* MessageStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C11AA4F20FD59C700351FBD /* MessageStatusView.swift */; }; 4C13C9F620E57BA30089A98B /* ColorPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C13C9F520E57BA30089A98B /* ColorPickerViewController.swift */; }; 4C20B2B720CA0034001BAC90 /* ThreadViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4542DF51208B82E9007B4E76 /* ThreadViewModel.swift */; }; @@ -1080,6 +1081,7 @@ 45FBC59A1DF8575700E9B410 /* CallKitCallManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CallKitCallManager.swift; sourceTree = ""; }; 45FBC5D01DF8592E00E9B410 /* SignalCall.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignalCall.swift; sourceTree = ""; }; 45FDA43420A4D22700396358 /* OWSNavigationBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OWSNavigationBar.swift; sourceTree = ""; }; + 4C090A1A210FD9C7001FD7F9 /* HapticFeedback.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = HapticFeedback.swift; path = UserInterface/HapticFeedback.swift; sourceTree = ""; }; 4C11AA4F20FD59C700351FBD /* MessageStatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageStatusView.swift; sourceTree = ""; }; 4C13C9F520E57BA30089A98B /* ColorPickerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPickerViewController.swift; sourceTree = ""; }; 4C20B2B820CA10DE001BAC90 /* ConversationSearchViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationSearchViewController.swift; sourceTree = ""; }; @@ -1855,6 +1857,7 @@ isa = PBXGroup; children = ( 450DF2071E0DD29E003D14BE /* Notifications */, + 4C090A1A210FD9C7001FD7F9 /* HapticFeedback.swift */, 34FD936E1E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.h */, 34FD936F1E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.m */, 34B3F8331E8DF1700035BE1A /* ViewControllers */, @@ -3254,6 +3257,7 @@ 34A55F3720485465002CC6DE /* OWS2FARegistrationViewController.m in Sources */, 340FC8AD204DAC8D007AEB0F /* OWSLinkedDevicesTableViewController.m in Sources */, 340FC8AA204DAC8D007AEB0F /* NotificationSettingsViewController.m in Sources */, + 4C090A1B210FD9C7001FD7F9 /* HapticFeedback.swift in Sources */, 3496744F2076ACD000080B5F /* LongTextViewController.swift in Sources */, 34FD93701E3BD43A00109093 /* OWSAnyTouchGestureRecognizer.m in Sources */, 34B3F8931E8DF1710035BE1A /* SignalsNavigationController.m in Sources */, diff --git a/Signal/src/UserInterface/HapticFeedback.swift b/Signal/src/UserInterface/HapticFeedback.swift new file mode 100644 index 000000000..beb47fd6a --- /dev/null +++ b/Signal/src/UserInterface/HapticFeedback.swift @@ -0,0 +1,51 @@ +// +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. +// + +import Foundation + +protocol HapticAdapter { + func selectionChanged() +} + +class LegacyHapticAdapter: NSObject, HapticAdapter { + + // MARK: HapticAdapter + + func selectionChanged() { + // do nothing + } +} + +@available(iOS 10, *) +class FeedbackGeneratorHapticAdapter: NSObject, HapticAdapter { + let selectionFeedbackGenerator: UISelectionFeedbackGenerator + + override init() { + selectionFeedbackGenerator = UISelectionFeedbackGenerator() + selectionFeedbackGenerator.prepare() + } + + // MARK: HapticAdapter + + func selectionChanged() { + selectionFeedbackGenerator.selectionChanged() + selectionFeedbackGenerator.prepare() + } +} + +class HapticFeedback: HapticAdapter { + let adapter: HapticAdapter + + init() { + if #available(iOS 10, *) { + adapter = FeedbackGeneratorHapticAdapter() + } else { + adapter = LegacyHapticAdapter() + } + } + + func selectionChanged() { + adapter.selectionChanged() + } +} diff --git a/Signal/src/ViewControllers/MenuActionsViewController.swift b/Signal/src/ViewControllers/MenuActionsViewController.swift index 0e20c2f92..cf9f22813 100644 --- a/Signal/src/ViewControllers/MenuActionsViewController.swift +++ b/Signal/src/ViewControllers/MenuActionsViewController.swift @@ -261,6 +261,9 @@ class MenuActionSheetView: UIView, MenuActionViewDelegate { private let actionStackView: UIStackView private var actions: [MenuAction] private var actionViews: [MenuActionView] + private var hapticFeedback: HapticFeedback + private var hasEverHighlightedAction = false + weak var delegate: MenuActionSheetDelegate? override var bounds: CGRect { @@ -281,6 +284,7 @@ class MenuActionSheetView: UIView, MenuActionViewDelegate { actions = [] actionViews = [] + hapticFeedback = HapticFeedback() super.init(frame: frame) @@ -371,7 +375,13 @@ class MenuActionSheetView: UIView, MenuActionViewDelegate { unhighlightAllActionViews() return } + + if hasEverHighlightedAction, !touchedView.isHighlighted { + self.hapticFeedback.selectionChanged() + } touchedView.isHighlighted = true + hasEverHighlightedAction = true + self.actionViews.filter { $0 != touchedView }.forEach { $0.isHighlighted = false } } @@ -441,7 +451,6 @@ class MenuActionView: UIButton { override var isHighlighted: Bool { didSet { - Logger.debug("\(logTag) in \(#function) \(oldValue) -> \(isHighlighted)") self.backgroundColor = isHighlighted ? UIColor.ows_light10 : UIColor.white } }