UIWindow 子类:Touches 事件不会被触发
Posted
技术标签:
【中文标题】UIWindow 子类:Touches 事件不会被触发【英文标题】:UIWindow subclass: Touches event not get fired 【发布时间】:2016-08-31 15:51:27 【问题描述】:我想在我当前的项目中实现会话时间功能。因此,我试图继承 UIWindow
并覆盖 touchesBegan
和 touchesEnded
方法。
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
但问题是 touchesBegan
和 touchesEnded
没有被调用。我无法弄清楚我做错了什么。
【问题讨论】:
也许这个项目会对你有所帮助:github.com/marqeta/mqtimeout 请向我们展示您的整个 app delegate 文件,因为我对private let baseWindow = ...
行的感觉非常糟糕,这似乎没有任何合理的用途,所以,请,整个文件会更健谈。
【参考方案1】:
不会为您的窗口调用touchesBegan(_:with:)
API,除非没有其他人来捕获触摸事件。通常情况并非如此,因为您希望您的 UI 元素接收触摸。
您要在窗口子类中实现的是sendEvent(:_)
并将您的逻辑放在那里。不要忘记调用超级实现来传递事件。
使用这种方法的一个小问题是您会听到一些不是触摸事件的事件,但这可能不是问题,因为它们大多是用户生成的。
【讨论】:
【参考方案2】:而不是继承UIWindow
。您可以在AppDelegate
的窗口中添加UITapGestureRecognizer
。
let gestureRecogniger = UITapGestureRecognizer(target: self, action: #selector(yourSelector)) // Implement your selector
gestureRecogniger.cancelsTouchesInView = false
window?.addGestureRecognizer(gestureRecogniger)
如果您需要考虑除点击以外的其他触摸,请同时使用 UIPanGestureRecognizer
和 UITapGestureRecognizer
。
如果您的子视图有自己的手势识别器,请添加此扩展
extension AppDelegate: UIGestureRecognizerDelegate
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool
return true
然后做
gestureRecogniger.delegate = self
【讨论】:
这只会捕捉点击,而不是触摸。它也不能很好地与具有自己的手势识别器的子视图一起使用。 哇的反对票雨。 :) 令人惊讶的是,不同的人以不同的方式使用选票。无论如何..有办法解决你所说的问题。查看我的更新答案。【参考方案3】:我尝试继承 UIWindow 并覆盖方法 touchesBegan, touchesEnded 当窗口有一个 rootViewController 检查演示项目时,这些方法被调用。 Sample app TouchTest
也检查这个方法 - (void)sendEvent:(UIEvent *)event
根据文档:您可以调用此方法将自定义事件分派到窗口的响应程序链。 窗口对象将触摸事件分派给发生触摸的视图,并将其他类型的事件分派给最合适的目标对象
【讨论】:
【参考方案4】:跟踪会话的更好方法是注册UIApplication
通知,例如UIApplicationDidEnterBackgroundNotification
和UIApplicationDidFinishLaunchingNotification
。
应用程序通知的完整列表位于UIApplication
class reference 的底部。您可以创建一个会话跟踪器类来干净地监听这些,而不会干扰代码的其他部分。
【讨论】:
以上是关于UIWindow 子类:Touches 事件不会被触发的主要内容,如果未能解决你的问题,请参考以下文章
Apple 文档在谈论其他哪些 UIWindow 接收触摸事件?