Swift/iOS13 - UIApplication.shared.delegate.window?.rootViewController?.present() 来自自定义类

Posted

技术标签:

【中文标题】Swift/iOS13 - UIApplication.shared.delegate.window?.rootViewController?.present() 来自自定义类【英文标题】:Swift/iOS13 - UIApplication.shared.delegate.window?.rootViewController?.present() from custom class 【发布时间】:2019-10-25 07:10:48 【问题描述】:

我在 Xcode11 中创建了一个新的 Storyboard 项目,并尝试像这样从 自定义类 呈现一个 ViewController(在旧项目中工作得很好):

let appDelegate = UIApplication.shared.delegate as! AppDelegate
let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc : UIViewController = storyboard.instantiateViewController(withIdentifier: "NotificationVC") as UIViewController
appDelegate.window?.makeKeyAndVisible()
appDelegate.window?.rootViewController?.present(vc, animated: true, completion: nil)

当然现在这不起作用,因为 AppDelegate 中不再有窗口变量已被移动到 SceneDelegate。

错误: Value of type 'AppDelegate' has no member 'window'

您现在如何使这段代码工作?

我想做的事:

当用户点击/点击推送通知托盘时,我试图显示一个 ViewController。

编辑:现在我可以通过在 SceneDelegate 中创建一个私有静态变量并在我的自定义类中访问该变量来使其工作:

SceneDelegate.swift

private(set) static var shared: SceneDelegate?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) 

    guard let _ = (scene as? UIWindowScene) else  return 
    Self.shared = self

CustomClass.swift

let sceneDeleage = SceneDelegate.shared
let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc : UIViewController = storyboard.instantiateViewController(withIdentifier: "NotificationVC") as UIViewController
sceneDeleage?.window?.makeKeyAndVisible()
sceneDeleage?.window?.rootViewController?.present(vc, animated: true, completion: nil)

这里可能不建议这样做:https://***.com/a/58547992/9511942,但它可以工作

EDIT2:感谢https://***.com/a/58557634/9511942,这是我的另一个解决方案

    let window = UIApplication.shared.windows.first
    let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    let vc : UIViewController = storyboard.instantiateViewController(withIdentifier: "NotificationVC") as UIViewController
    window?.makeKeyAndVisible()
    window?.rootViewController = vc

如果有人找到更好的解决方案,请分享。

【问题讨论】:

检查您的应用委托文件是否有var window: UIWindow? 它不存在,因为新的 xcode11 项目在 scenedelegate 中带有 windows 变量。如果我在 appdelegate 中添加它,我的代码什么也不做,因为它是 nil,如果我强制打开 window!,我会得到 Fatal error: Unexpectedly found nil while unwrapping an Optional value UIApplication.shared.delegate equivalent for SceneDelegate xcode11?的可能重复 它实际上不是重复的,我只是不想在 1 中问 2 个问题。那里的答案在 ViewController 中工作得很好。但我无法在自定义类中实现它。 使用 UIApplication.shared.windows 属性获取应用程序窗口。请参考developer.apple.com/documentation/uikit/uiapplication/… 【参考方案1】:

使用UIApplication.shared.windows 属性获取应用程序窗口。请参考https://developer.apple.com/documentation/uikit/uiapplication/1623104-windows

【讨论】:

使用UIApplication.shared.windows如何解决问题?一个应用可以有多个场景。自定义类如何仅通过迭代应用程序窗口就知道哪个窗口是正确的窗口?

以上是关于Swift/iOS13 - UIApplication.shared.delegate.window?.rootViewController?.present() 来自自定义类的主要内容,如果未能解决你的问题,请参考以下文章

Swift/iOS13 - UIApplication.shared.delegate.window?.rootViewController?.present() 来自自定义类

Swift IOS 13,IAP - “无法连接到 Itunes Connect”

Swift iOS 13 推送通知设备令牌在 javascript/php/typescript 中转换

Swift - iOS 8 中的 UIPopoverController

Swift (iOS) 代码覆盖率和 XCTest (mock)

Swift 3,iOS 10 - 以编程方式声明 UIStackView 不适合屏幕宽度