【问题标题】:How set rootViewController in Scene Delegate iOS 13如何在场景委托 iOS 13 中设置 rootViewController
【发布时间】:2020-01-30 22:51:57
【问题描述】:

在 UIKit iOS 13 更改之前,如何在 SceneDelegate 设置 rootViewController?

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?


    @available(iOS 13.0, *)
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let _ = (scene as? UIWindowScene) else { return }

    }

【问题讨论】:

    标签: swift uikit ios13


    【解决方案1】:

    仅供参考,因为 SwiftUI 不使用情节提要,如果您只是创建一个新的 SwiftUI 项目,它将为您提供代码;您需要做的就是将 UIHostingViewController 替换为您想要的根 VC,如下所示:

    class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    
      var window: UIWindow?
    
      func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = MyRootViewController()
            self.window = window
            window.makeKeyAndVisible()
        }
      }
    

    【讨论】:

      【解决方案2】:

      如果您发现自己需要从代理(iOS12 和 iO13)访问窗口以更改 rootviewcontroller,这里有几个我使用的扩展:

         extension UIViewController {
              var appDelegate: AppDelegate {
              return UIApplication.shared.delegate as! AppDelegate
          }
          
          var sceneDelegate: SceneDelegate? {
              guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
                  let delegate = windowScene.delegate as? SceneDelegate else { return nil }
               return delegate
          }
      }
      
      extension UIViewController {
          var window: UIWindow? {
              if #available(iOS 13, *) {
                  guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
                      let delegate = windowScene.delegate as? SceneDelegate, let window = delegate.window else { return nil }
                         return window
              }
              
              guard let delegate = UIApplication.shared.delegate as? AppDelegate, let window = delegate.window else { return nil }
              return window
          }
      }
      

      【讨论】:

        【解决方案3】:

        如果您不需要支持多窗口支持,请忽略它。我跟进this answer

        当您启动新项目时,它会自动创建清单和 SceneDelegate 类。忽略多窗口支持后,您可以像以前一样再次使用应用委托窗口。

        【讨论】:

          【解决方案4】:

          像这样:

          class SceneDelegate: UIResponder, UIWindowSceneDelegate {
          
             var window: UIWindow?
             func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
                   // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
                   // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
                   // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
                  guard let _ = (scene as? UIWindowScene) else { return }
          
                  let rootVC = self.window?.rootViewController 
              }
              // ... the rest of SceneDelegate
          }
          

          here所见。

          【讨论】:

            猜你喜欢
            • 2020-01-30
            • 2020-01-24
            • 1970-01-01
            • 2013-02-23
            • 2021-03-09
            • 1970-01-01
            • 2021-11-14
            • 2014-11-29
            • 2020-02-20
            相关资源
            最近更新 更多