有没有办法在“UIApplication”或“UIWindow”级别检测 VoiceOver 焦点变化/用户交互?

Is there a way to detect VoiceOver focus change / user interaction at the `UIApplication` or `UIWindow` level?

我正在开发的应用程序的一个功能是“空闲超时”——基本上,如果用户不与该应用程序交互超过五分钟,出于隐私/安全原因,他们的会话就会结束。

目前这是通过覆盖应用程序委托中的 sendEvent(_ event: UIEvent) 并重置计时器来实现的。

但是,我注意到当用户使用 VoiceOver 与应用交互时根本不会调用 sendEvent(_ event: UIEvent)

在用户双击激活控件时调用,但不是调用焦点更改、交互使用 .adjustable 控件,依此类推。

这意味着如果用户在 table 视图中滑动一长串行,例如,不会调用 sendEvent(_ event: UIEvent) 并且用户可能会超时应用程序,即使他们正在与之交互。

有没有办法在 UIApplicationUIWindow 级别检测 VoiceOver 焦点变化或交互,或者可以订阅一个通知以获得干净的解决方案?

我发现的最接近的解决方案建议在单个视图上使用 UIAccessibilityFocus 协议,但这感觉起来可能非常混乱并且涉及很多子类化 ()。

对于适用于 VoiceOver 和非 VoiceOver 用户的空闲超时的任何不同建议也将不胜感激 - 很可能我错过了一些东西。

所以我在这里找到了解决方案,现在我正在踢自己。

UIAccessibility.elementFocusedNotification 是关键 (https://developer.apple.com/documentation/uikit/uiaccessibility/1620210-elementfocusednotification).

所以解决方案可能类似于:

NotificationCenter.default.addObserver(self,
                                       selector: #selector(self.accessibilityElementFocussed(notification:)),
                                       name: UIAccessibility.elementFocusedNotification,
                                       object: nil)

@objc private func accessibilityElementFocussed(notification: NSNotification) {
    // Reset your idle timer here.
}

希望这能帮助到一些人 - 我在网上看到很多空闲计时器的解决方案都没有考虑到 VoiceOver 用户。