David
David

Reputation: 2721

Is it possible to detect gesture happening in one place for all of them?

Is it possible to detect gesture happening on the screen in a central place in iOS, for example, in AppDelegate I suppose. I know we can set gestures recognizers to each view. But I want to know in a central place that all pan/scroll behaviour is happening. So some flags could be set when gesture behaviour occurred.

Upvotes: 1

Views: 1040

Answers (3)

lewis
lewis

Reputation: 3202

iOS 13+ with Scene Delegate

user3581248 put me on the right track here, I have updated it for iOS 13.

// SceneDelegate
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    guard let _ = (scene as? UIWindowScene) else { return }

    setupGlobalAccessToDebugScreen()
}

func setupGlobalAccessToDebugScreen() {
    let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tapped))
    tapGesture.delegate = self
    tapGesture.numberOfTapsRequired = 6
    self.window?.addGestureRecognizer(tapGesture)
}

@objc func tapped() {
    // your action
}

// pass taps on to regular controls, don't block them
extension SceneDelegate: UIGestureRecognizerDelegate {
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
       return true
    }
}

Upvotes: 1

user3581248
user3581248

Reputation: 1014

You could go this way:

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    let tap = UITapGestureRecognizer(target: self, action: #selector(tapped))
    window?.addGestureRecognizer(tap)
    return true
 }

 func tapped() {
    print("tapped")
 }

However this will not always work, since any interactive UI elements that you add will intercept the gestures. But there's a solution that will allow you to find out ALWAYS:

 (...)   
 let tap = UITapGestureRecognizer(target: self, action: #selector(tapped))
 tap.delegate = self
 window?.addGestureRecognizer(tap)
 (...)

and then implement the delegate's:

 extension AppDelegate: UIGestureRecognizerDelegate {
     func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        return true
     }
 }

This way it will not disrupt any normal behaviour of the app but you will be able to detect all touches in the gesture recognizer delegate's method.

Upvotes: 3

brianLikeApple
brianLikeApple

Reputation: 4371

View or View Controller is the place you should put touch event or gesture, as it is logically good to organise or maintain your code.

But having said that, sometimes, especially in cocoa development, you may have several events having exact same function. e.g. You can have a function button in the application and also you may have same function menu item on the top bar in cocoa application. In this case, you should put code in one place for sharing code.

You can put your change flags code in the delegate, and call it from the gesture code in the view or view controller.

Upvotes: 0

Related Questions