[英]How to track all touches across SwiftUI app
我正在嘗試在 SwiftUI 應用程序中實現鎖定屏幕。
我需要跟蹤每個事件以重新啟動鎖定計時器。
在 UIKit 應用程序中,我使用了這種方法 - 覆蓋 UIApplication,它允許了解應用程序中的任何事件:
override func sendEvent(_ event: UIEvent) {
super.sendEvent(event)
switch event.type {
case .touches:
// Post Notification or Delegate here
default:
break
}
}
但是在 SwiftUI 中它不再受支持。 我試着添加
.onTapGesture {}
到根 ContentView,但它沒有按預期工作。
有沒有辦法避免添加
.onTapGesture {}
應用程序中的每個視圖?
這是一個可能的解決方案:
@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
}
}
基於pawello2222 的解決方案,我添加了 UIPanGestureRecognizer 以便能夠在應用程序周圍滾動或滑動時進行識別。 還添加了一個通知觀察器來識別從鍵盤輸入文本時的情況。 解決方案如下所示:
@main
struct YourApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.onAppear {
// Interaction recognizer implementation
UIApplication.shared.addInteractionRecognizer()
}
}
}
}
extension UIApplication {
func addInteractionRecognizer() {
// Notification observer to track text changes from keyboard
NotificationCenter.default.addObserver(self, selector: #selector(didInteractWithApp), name: UITextField.textDidChangeNotification, object: nil)
guard let window = windows.first else { return }
// Gestures recognizers to track
let gestureRecognizers = [
UITapGestureRecognizer(target: self, action: #selector(didInteractWithApp)),
UIPanGestureRecognizer(target: self, action: #selector(didInteractWithApp))
]
gestureRecognizers.forEach {
$0.requiresExclusiveTouchType = false
$0.cancelsTouchesInView = false
$0.delegate = self
window.addGestureRecognizer($0)
}
}
@objc func didInteractWithKeyboard() {
// Restart the lock timer
}
@objc func didInteractWithApp(_ sender: UIGestureRecognizer) {
// Optional: Validate UIPanGestureRecognizer has ended, cancelled or failed, to prevent overloading for restarting timer. Remove if not needed
let allowedStates: [UIGestureRecognizer.State] = [.ended, .cancelled, .failed]
if sender as? UIPanGestureRecognizer != nil, !allowedStates.contains(sender.state) {
return
}
// Restart the lock timer
}
}
extension UIApplication: UIGestureRecognizerDelegate {
public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
// Set to true to recognize gestures specified above while allowing user interact with other gestures in the app and not to block them with them
return true
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.