tvOS 中的自定义 UIWindow 使应用程序无法响应键盘输入

Custom UIWindow in tvOS makes app unresponsive to keyboard input

在 tvOS 中,如果我使用自定义 UIWindow 实例,应用会停止响应模拟器中的键盘和遥控器。我应该在 UIWindow 实例上设置任何变量或 属性 吗?

class AppDelegate: UIResponder, UIApplicationDelegate {

    lazy var window : UIWindow? = {
        let screen = UIScreen.main
        let w = UIWindow(frame: screen.bounds)
        return w
    }()

    // ...
}

原因是我需要子类化 UIWindow 以具有自定义色调颜色并通过 traitCollectionDidChange 响应 Dark/Light 模式更改。

这是在 tvOS 10.2.1 中

您需要在您的 UIWindow 实例中调用 makeKeyAndVisible()

https://developer.apple.com/reference/uikit/uiwindow/1621601-makekeyandvisible

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func applicationDidFinishLaunching(_ application: UIApplication) {
        window = UIWindow(frame: UIScreen.main.bounds)
        window?.rootViewController = yourRootViewController
        window?.makeKeyAndVisible()
    }
}

显然,如果需要自定义 UIWindow,则还需要实例化故事板并呈现 window。仅仅提供一个 UIWindow 实例是不够的。

首先,从主应用程序的 Info.plist 文件中删除 密钥 UIMainStoryboardFile

然后在应用程序中添加代码并启动处理程序到:

  1. 实例化 window 并分配给应用委托的 属性。
  2. 实例化故事板。
  3. 实例化初始视图控制器
  4. 将视图控制器分配给 window。
  5. 显示 window.
    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {

        var window : UIWindow?

        // ...

        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

            window = MainWindow(frame: UIScreen.main.bounds)
            // We need to instantiate our own storyboard instead of specifying one in `Info.plist` since we need our own custom `UIWindow` instance.
            // Otherwise if we just create the custom UIWindow instance and let the system creates a storyboard,
            // then the application won't respond to the keyboard/remote (user input).
            let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
            window?.rootViewController = storyboard.instantiateInitialViewController()
            defer {
                window?.makeKeyAndVisible()
            }

            // ... All other setup code
        }

        // ...

    }