From edd1e55cbbe854fef2ee2c7d02544acaaa54df30 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Thu, 26 Jan 2023 21:28:56 -0500 Subject: [PATCH] Unify haptic feedback Closes #154 --- Documentation/Haptic Feedback.md | 7 +++++++ .../Duckable/DuckableContainerViewController.swift | 2 +- .../FastAccountSwitcherViewController.swift | 14 +++++++------- .../FollowRequestNotificationTableViewCell.swift | 4 ++-- Tusker/Views/Poll/PollOptionsView.swift | 6 +++--- Tusker/Views/Poll/StatusPollView.swift | 2 +- 6 files changed, 21 insertions(+), 14 deletions(-) create mode 100644 Documentation/Haptic Feedback.md diff --git a/Documentation/Haptic Feedback.md b/Documentation/Haptic Feedback.md new file mode 100644 index 00000000..b56b4092 --- /dev/null +++ b/Documentation/Haptic Feedback.md @@ -0,0 +1,7 @@ +# Haptic Feedback + +## Selection changed +`UISelectionFeedbackGenerator` + +## Actions +On success, `UIImpactFeedbackGenerator` with the `.light` style. On error, `UINotificationFeedbackGenerator` with the `.error` type. diff --git a/Packages/Duckable/Sources/Duckable/DuckableContainerViewController.swift b/Packages/Duckable/Sources/Duckable/DuckableContainerViewController.swift index 32336b42..e555f683 100644 --- a/Packages/Duckable/Sources/Duckable/DuckableContainerViewController.swift +++ b/Packages/Duckable/Sources/Duckable/DuckableContainerViewController.swift @@ -62,7 +62,7 @@ public class DuckableContainerViewController: UIViewController, DuckableViewCont guard case .idle = state else { if animated, case .ducked(_, placeholder: let placeholder) = state { - UIImpactFeedbackGenerator(style: .soft).impactOccurred() + UIImpactFeedbackGenerator(style: .light).impactOccurred() let origConstant = placeholder.topConstraint.constant UIView.animateKeyframes(withDuration: 0.4, delay: 0) { UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.5) { diff --git a/Tusker/Screens/Fast Account Switcher/FastAccountSwitcherViewController.swift b/Tusker/Screens/Fast Account Switcher/FastAccountSwitcherViewController.swift index 57f3ac51..aa4ca4cd 100644 --- a/Tusker/Screens/Fast Account Switcher/FastAccountSwitcherViewController.swift +++ b/Tusker/Screens/Fast Account Switcher/FastAccountSwitcherViewController.swift @@ -24,7 +24,7 @@ class FastAccountSwitcherViewController: UIViewController { private(set) var accountViews: [FastSwitchingAccountView] = [] private var lastSelectedAccountViewIndex: Int? - private var selectionChangedFeedbackGenerator: UIImpactFeedbackGenerator? + private var selectionChangedFeedbackGenerator: UISelectionFeedbackGenerator? private var touchBeganFeedbackWorkItem: DispatchWorkItem? var itemOrientation: ItemOrientation = .iconsTrailing @@ -148,7 +148,7 @@ class FastAccountSwitcherViewController: UIViewController { private func switchAccount(newIndex: Int, hapticFeedback: Bool = true) { if newIndex == 0 { // add account placeholder if hapticFeedback { - selectionChangedFeedbackGenerator?.impactOccurred() + selectionChangedFeedbackGenerator?.selectionChanged() } selectionChangedFeedbackGenerator = nil @@ -160,7 +160,7 @@ class FastAccountSwitcherViewController: UIViewController { if account.id != LocalData.shared.mostRecentAccountID { if hapticFeedback { - selectionChangedFeedbackGenerator?.impactOccurred() + selectionChangedFeedbackGenerator?.selectionChanged() } selectionChangedFeedbackGenerator = nil @@ -178,8 +178,8 @@ class FastAccountSwitcherViewController: UIViewController { @objc private func handleLongPress(_ recognizer: UIGestureRecognizer) { switch recognizer.state { case .began: - selectionChangedFeedbackGenerator = UIImpactFeedbackGenerator(style: .medium) - selectionChangedFeedbackGenerator?.impactOccurred() + UIImpactFeedbackGenerator(style: .heavy).impactOccurred() + selectionChangedFeedbackGenerator = UISelectionFeedbackGenerator() selectionChangedFeedbackGenerator?.prepare() show() @@ -231,7 +231,7 @@ class FastAccountSwitcherViewController: UIViewController { lastSelectedAccountViewIndex = selectedAccountViewIndex if hapticFeedback { - selectionChangedFeedbackGenerator?.impactOccurred(intensity: 0.5) + selectionChangedFeedbackGenerator?.selectionChanged() selectionChangedFeedbackGenerator?.prepare() } } @@ -260,7 +260,7 @@ class FastAccountSwitcherViewController: UIViewController { // if the user is merely tapping, not initiating a pan, we don't want to trigger a double-impact // if the tap ends very quickly, this will be cancelled touchBeganFeedbackWorkItem = DispatchWorkItem { - self.selectionChangedFeedbackGenerator?.impactOccurred(intensity: 0.5) + self.selectionChangedFeedbackGenerator?.selectionChanged() self.selectionChangedFeedbackGenerator?.prepare() self.touchBeganFeedbackWorkItem = nil } diff --git a/Tusker/Views/Notifications/FollowRequestNotificationTableViewCell.swift b/Tusker/Views/Notifications/FollowRequestNotificationTableViewCell.swift index f48688b3..aa7877c4 100644 --- a/Tusker/Views/Notifications/FollowRequestNotificationTableViewCell.swift +++ b/Tusker/Views/Notifications/FollowRequestNotificationTableViewCell.swift @@ -146,7 +146,7 @@ class FollowRequestNotificationTableViewCell: UITableViewCell { do { _ = try await mastodonController.run(request) - UINotificationFeedbackGenerator().notificationOccurred(.success) + UIImpactFeedbackGenerator(style: .light).impactOccurred() self.actionButtonsStackView.isHidden = true self.addLabel(NSLocalizedString("Rejected", comment: "rejected follow request label")) } catch let error as Client.Error { @@ -172,7 +172,7 @@ class FollowRequestNotificationTableViewCell: UITableViewCell { do { _ = try await mastodonController.run(request) - UINotificationFeedbackGenerator().notificationOccurred(.success) + UIImpactFeedbackGenerator(style: .light).impactOccurred() self.actionButtonsStackView.isHidden = true self.addLabel(NSLocalizedString("Accepted", comment: "accepted follow request label")) } catch let error as Client.Error { diff --git a/Tusker/Views/Poll/PollOptionsView.swift b/Tusker/Views/Poll/PollOptionsView.swift index a8908ac5..3f5afd0e 100644 --- a/Tusker/Views/Poll/PollOptionsView.swift +++ b/Tusker/Views/Poll/PollOptionsView.swift @@ -26,7 +26,7 @@ class PollOptionsView: UIControl { private let animationDuration: TimeInterval = 0.1 private let scaledTransform = CGAffineTransform(scaleX: 0.95, y: 0.95) - private let generator = UIImpactFeedbackGenerator(style: .soft) + private let generator = UISelectionFeedbackGenerator() override var isEnabled: Bool { didSet { @@ -110,7 +110,7 @@ class PollOptionsView: UIControl { } animator.startAnimation() - generator.impactOccurred() + generator.selectionChanged() generator.prepare() return true @@ -139,7 +139,7 @@ class PollOptionsView: UIControl { } if newIndex != nil { - generator.impactOccurred() + generator.selectionChanged() generator.prepare() } } diff --git a/Tusker/Views/Poll/StatusPollView.swift b/Tusker/Views/Poll/StatusPollView.swift index a428becf..44023954 100644 --- a/Tusker/Views/Poll/StatusPollView.swift +++ b/Tusker/Views/Poll/StatusPollView.swift @@ -148,7 +148,7 @@ class StatusPollView: UIView { voteButton.isEnabled = false voteButton.disabledTitle = "Voted" - UIImpactFeedbackGenerator(style: .medium).impactOccurred() + UIImpactFeedbackGenerator(style: .light).impactOccurred() let request = Poll.vote(poll!.id, choices: optionsView.checkedOptionIndices) mastodonController.run(request) { (response) in