【问题标题】:Presenting a ViewController from UIApplication subclass从 UIApplication 子类呈现 ViewController
【发布时间】:2018-04-29 22:45:20
【问题描述】:

我的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)
    }
}

【问题讨论】:

  • 我能知道你为什么想要这样的东西吗?
  • @Sh_Khan 这是一个博物馆的应用程序。当被访问者放弃时需要自动返回开始屏幕。

标签: ios swift uiviewcontroller uiapplication


【解决方案1】:

实现非活动计时器不需要子类化 UIApplication。根据UIApplication documentation 的子类化注释,只有在极少数情况下才需要子类化:

大多数应用程序不需要子类化 UIApplication。相反,使用应用委托来管理系统和应用之间的交互。

如果您的应用必须先于系统处理传入事件(这种情况非常罕见),您可以实现自定义事件或动作分派机制。为此,继承 UIApplication 并覆盖 sendEvent(:) 和/或 sendAction(:to:from:for:) 方法。对于您拦截的每个事件,在处理完事件后通过调用 [super sendEvent:event] 将其分派回系统。很少需要拦截事件,您应该尽可能避免。

正如您在问题中已经提到的,您可以从/通过 AppDelegate 访问所需的一切。那么,为什么不通过 AppDelegate 处理 / 中的非活动超时呢?

【讨论】:

  • 因为我确实需要覆盖sendEvent(:)。每次用户触摸屏幕时,我都需要重新启动计时器。
【解决方案2】:

我最终自己解决了这个问题:

//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()
}

【讨论】:

    猜你喜欢
    • 2018-02-27
    • 1970-01-01
    • 2018-03-07
    • 2020-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多