Как отслеживать все касания в приложении SwiftUI

Я пытаюсь реализовать блокировку экрана в приложении 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 {}

для каждого просмотра в приложении?


person Owen Rivera    schedule 16.09.2020    source источник
comment
Вы можете увидеть этот ответ: stackoverflow.com/a/60010955/8697793 - вместо endEditing вы можете вызвать свою пользовательскую функцию.   -  person pawello2222    schedule 16.09.2020
comment
Да, это отличный ответ, но есть некоторые проблемы с iOS 14 без Scenedelegate и Window.   -  person Owen Rivera    schedule 17.09.2020


Ответы (1)


Вот возможное решение:

@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
    }
}
person pawello2222    schedule 16.09.2020
comment
У меня такая ошибка при использовании этого кода 'windows' was deprecated in iOS 15.0: Use UIWindowScene.windows on a relevant window scene instead - person Roland Lariotte; 14.06.2021