UIWindow 子类:未触发 Touches 事件

UIWindow subclass: Touches event not get fired

我想在我当前的项目中实现会话时间功能。因此,为此我正在尝试子类化 UIWindow 并覆盖 touchesBegantouchesEnded 方法。

class BaseWindow: UIWindow {

    convenience init() {
        self.init(frame: UIScreen.mainScreen().bounds)
    }

    private var sessionTimeOutTimer: NSTimer?

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        sessionTimeOutTimer?.invalidate()
    }

    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        sessionTimeOutTimer = NSTimer.scheduledTimerWithTimeInterval(60, target: CIAppManager.sharedManger(), selector: #selector(CIAppManager.sessionTimeOut), userInfo: nil, repeats: false)
    }
}

我在应用委托中这样做了

private let baseWindow = BaseWindow()
var window: UIWindow? {
    get {
        return baseWindow
    }
    set {}
}

但问题是 touchesBegantouchesEnded 没有被调用。我无法弄清楚我做错了什么。

touchesBegan(_:with:) API 不会为您的 window 调用,除非没有其他人捕获触摸事件。通常情况下不会出现这种情况,因为您希望 UI 元素接收触摸。

您想在 window 子类中实现的是 sendEvent(:_) 并将您的逻辑放在那里。不要忘记调用超级实现来传递事件。

使用这种方法的一个小注意事项是您会听到一些不是触摸事件的事件,但这可能不是问题,因为它们大多是用户生成的。

而不是子类化 UIWindow。您可以在 AppDelegate 的 window 中添加 UITapGestureRecognizer

let gestureRecogniger = UITapGestureRecognizer(target: self, action: #selector(yourSelector)) // Implement your selector
gestureRecogniger.cancelsTouchesInView = false
window?.addGestureRecognizer(gestureRecogniger)

如果您需要考虑点击以外的其他触摸,请同时使用 UIPanGestureRecognizerUITapGestureRecognizer

如果您的子视图有自己的手势识别器,请添加此扩展程序

extension AppDelegate: UIGestureRecognizerDelegate {
    func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
}

并做

gestureRecogniger.delegate = self

我尝试子类化 UIWindow 并覆盖方法 touchesBegan、touchesEnded 当 window 让 rootViewController 检查演示项目时,这些方法被调用。 Sample app TouchTest

也检查这个方法 - (void)sendEvent:(UIEvent *)event

根据文档:您可以调用此方法将自定义事件分派到 window 的响应程序链。 Window 对象将触摸事件分派到发生触摸的视图,并将其他类型的事件分派到最合适的目标对象

跟踪会话的更好方法是注册 UIApplication 通知,例如 UIApplicationDidEnterBackgroundNotificationUIApplicationDidFinishLaunchingNotification

UIApplication class reference 底部提供了完整的应用程序通知列表。您可以创建一个会话跟踪器 class,在不干扰代码的其他部分的情况下干净地监听这些。