我在我的UIApplication
子类中运行了一个计时器,该计时器应该在用完时将用户发送到某个ViewController
。
我能够实例化我想要去的ViewController
...
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "StartVC")
...但我不知道如何实际呈现它。在AppDelegate
内部,我可以window.rootViewController
等。但这在我的UIApplication
子类。
我也试过self.windows[0].rootViewController
,但这始终只是应用启动时出现的第一个ViewController
。与self.keyWindow.rootViewController
相同。老实说,我不知道这两个属性是什么。
上下文的完整代码:
import Foundation
import UIKit
class MyApplication: UIApplication {
var inactivityTimer: Timer!
override init() {
super.init()
restartInactivityTimer()
}
@objc func timerExceeded() {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "StartVC")
//...here I would need to present "vc"
}
override func sendEvent(_ event: UIEvent) {
super.sendEvent(event)
restartInactivityTimer()
}
func restartInactivityTimer() {
if inactivityTimer != nil { inactivityTimer.invalidate() }
inactivityTimer = Timer.scheduledTimer(timeInterval: 2.0, target: self, selector: #selector(timerExceeded), userInfo: nil, repeats: false)
}
}
答案 0 :(得分:0)
实现不活动计时器不需要子类化UIApplication。根据{{3}}的子类注释,只应在极少数情况下才需要子类化:
大多数应用程序不需要子类化UIApplication。相反,使用应用程序委托来管理系统和应用程序之间的交互。
如果您的应用必须在系统执行之前处理传入事件(极少数情况),您可以实现自定义事件或操作调度机制。为此,子类化UIApplication并覆盖sendEvent( :)和/或sendAction(:to:from:for :)方法。对于您拦截的每个事件,在处理事件后通过调用[super sendEvent:event]将其发送回系统。很少需要拦截事件,如果可能的话你应该避免它。
正如您在问题中已经提到的,您可以通过AppDelegate访问所需的一切。那么,为什么不通过AppDelegate来处理不活动超时?
答案 1 :(得分:0)
我最终自己解决了这个问题:
//inside my UIApplication subclass
@objc func timerExceeded() {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "StartVC") as! StartVC
self.windows.first?.rootViewController = vc
self.windows.first?.makeKeyAndVisible()
}