I'm trying to implement a lock screen in the SwiftUI app.
I need to track every event in order to restart the lock timer.
In UIKit app, I used this approach - overriding UIApplication, which allows being aware of any event across the app:
override func sendEvent(_ event: UIEvent) {
super.sendEvent(event)
switch event.type {
case .touches:
// Post Notification or Delegate here
default:
break
}
}
But in SwiftUI it is not supported anymore. I tried to add
.onTapGesture {}
to the root ContentView, but it doesn't work as expected.
Is there any way to avoid adding
.onTapGesture {}
to every single view in the app?
Here is a possible solution:
@main
struct TestApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.onAppear(perform: UIApplication.shared.addTapGestureRecognizer)
}
}
}
extension UIApplication {
func addTapGestureRecognizer() {
guard let window = windows.first else { return }
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tapAction))
tapGesture.requiresExclusiveTouchType = false
tapGesture.cancelsTouchesInView = false
tapGesture.delegate = self
window.addGestureRecognizer(tapGesture)
}
@objc func tapAction(_ sender: UITapGestureRecognizer) {
print("tapped")
}
}
extension UIApplication: UIGestureRecognizerDelegate {
public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true // set to `false` if you don't want to detect tap during other gestures
}
}