在 iOS13 以前,大家的 Window 都是在 AppDelegate
里进行初始化:
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
if let window = window {
window.rootViewController = MainViewController()
window.makeKeyAndVisible()
}
}
}
到了 iOS13 增加了多窗口模式,Window 的初始化由原来的 AppDelegate
改到了新的 SceneDelegate
。
为了兼容之前的系统,Window 的初始化一般都这么写:
@available(iOS 13.0, *)
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
if let shardWindow = UIApplication.shared.delegate?.window {
window = shardWindow
window?.windowScene = windowScene
window?.makeKeyAndVisible()
}
}
}
运行的很好,看似没有什么问题。
很快你会发现,所有的 UIMenuController
都不能正常显示出来了。
原因是因为 Window 并不是 keyWindow,UIMenuController
只能在 keyWindow 上显示,所以系统菜单无法显示出来。
造成这个问题的原因是因为在 AppDelegate
过早的调用了 makeKeyAndVisible
。
然后在 SceneDelegate
里连接上 windowScene
后再调用 makeKeyAndVisible
是无效的。
这个问题从 iOS 13.0 到目前(iOS 13.3.1)都存在,看来是系统特性而不是 BUG。
解决方案很简单,iOS 13 下延迟调用 makeKeyAndVisible
就行了。
在 AppDelegate
里调整一下,如果是 iOS 13 就延迟设置为 keyWindow:
if let window = window {
window.rootViewController = MainViewController()
if #available(iOS 13.0, *) {
window.isHidden = false
} else {
window.makeKeyAndVisible()
}
}
问题解决,希望能帮助遇到同样问题的同学早点脱坑。