Skip to content

Commit

Permalink
feat: Detect both long and double touch events without slowing tap de…
Browse files Browse the repository at this point in the history
…tection over other tab items
  • Loading branch information
adrien-coye committed Jun 28, 2024
1 parent 9f145fa commit a58611a
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 27 deletions.
32 changes: 28 additions & 4 deletions kDrive/UI/Controller/MainTabViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ import kDriveResources
import UIKit

class MainTabViewController: UITabBarController, Restorable, PlusButtonObserver {
/// Tracking the last selection date to detect double tap
private var lastInteraction: Date?

/// Time between two tap events that feels alright for a double tap
private static let doubleTapInterval = TimeInterval(0.350)

// swiftlint:disable:next weak_delegate
var photoPickerDelegate = PhotoPickerDelegate()

Expand Down Expand Up @@ -251,13 +257,31 @@ extension MainTabViewController: MainTabBarDelegate {

extension MainTabViewController: UITabBarControllerDelegate {
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
if let homeViewController = (viewController as? UINavigationController)?.topViewController as? HomeViewController {
guard let navigationController = viewController as? UINavigationController else {
return false
}

defer {
lastInteraction = Date()
}

let topViewController = navigationController.topViewController
if let homeViewController = topViewController as? HomeViewController {
homeViewController.presentedFromTabBar()
}

if tabBarController.selectedViewController == viewController,
let viewController = (viewController as? UINavigationController)?.topViewController as? TopScrollable {
viewController.scrollToTop()
if tabBarController.selectedViewController == viewController {
// Detect double tap on menu
if let viewController = topViewController as? MenuViewController,
let lastDate = lastInteraction,
Date().timeIntervalSince(lastDate) <= Self.doubleTapInterval {
print("double tap detected")
return true
}

if let viewController = topViewController as? TopScrollable {
viewController.scrollToTop()
}
}

return true
Expand Down
42 changes: 19 additions & 23 deletions kDrive/UI/View/Menu/MainTabBar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ final class MainTabBar: UITabBar {
self.shapeLayer = shapeLayer
setupBackgroundGradient()
setupMiddleButton()
setupDoubleTapRecognizer()
setupGestureRecognizer()
}

override func layoutSubviews() {
Expand Down Expand Up @@ -165,32 +165,28 @@ final class MainTabBar: UITabBar {
centerButton.addTarget(self, action: #selector(centerButtonAction), for: .touchUpInside)
}

private func setupDoubleTapRecognizer() {
let doubleTap = UITapGestureRecognizer(target: self, action: #selector(Self.handleDoubleTap(recognizer:)))
doubleTap.numberOfTapsRequired = 2
addGestureRecognizer(doubleTap)
doubleTap.delaysTouchesBegan = false
private func setupGestureRecognizer() {
let longTouch = UILongPressGestureRecognizer(target: self,
action: #selector(Self.handleLongTouch(recognizer:)))
addGestureRecognizer(longTouch)
}

@objc func handleDoubleTap(recognizer: UITapGestureRecognizer) {
let touchPoint = recognizer.location(in: self)
@objc func handleLongTouch(recognizer: UITapGestureRecognizer) {
guard recognizer.state == .began else {
return
}

// Tap is over the 5th button
if touchPoint.x > bounds.width / 5 * 4 {
print("Double Tap profile")
@InjectService var accountManager: AccountManageable
guard let account = accountManager.accounts.values.randomElement() else {
fatalError("woops")
}
accountManager.switchAccount(newAccount: account)

// TODO: "Respring" with restoration code
guard let driveFileManager = try? accountManager.getFirstAvailableDriveFileManager(for: account.userId) else {
fatalError("woops V2")
}
let newMainTabViewController = MainTabViewController(driveFileManager: driveFileManager)
(UIApplication.shared.delegate as? AppDelegate)?.setRootViewController(newMainTabViewController)
// Touch is over the 5th button's x position
let touchPoint = recognizer.location(in: self)
guard touchPoint.x > bounds.width / 5 * 4 else {
return
}

let generator = UIImpactFeedbackGenerator(style: .light)
generator.impactOccurred()

print("Long touch")
// TODO: Nav to detail View, wait for AppNavigable to be available
}

@objc func centerButtonAction(sender: UIButton) {
Expand Down

0 comments on commit a58611a

Please sign in to comment.