简体   繁体   English

ViewDidLoad 被调用两次 iOS 13+

[英]ViewDidLoad gets called twice iOS 13+

I am developing an app for iOS 12+ and the fact that iOS 13 requires a SceneDelegate is causing me some problems when displaying the first ViewController programmatically, as I don't use storyboards.我正在为 iOS 12+ 开发一个应用程序,而 iOS 13 需要 SceneDelegate 的事实在以编程方式显示第一个 ViewController 时给我带来了一些问题,因为我不使用故事板。

In the AppDelegate.swift I use this code to present the ViewController for devices that don't have iOS 13 installed yet:在 AppDelegate.swift 中,我使用此代码为尚未安装 iOS 13 的设备显示 ViewController:

var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    FirebaseApp.configure()
    Database.database().isPersistenceEnabled = true

    IQKeyboardManager.shared.enable = true
    window = UIWindow()
    window?.rootViewController = ViewController()
    window?.makeKeyAndVisible()
    window?.backgroundColor = .main
    window?.rootViewController = UINavigationController(rootViewController: ViewController())
    return true
}

This works properly for those devices;这适用于这些设备; in the SceneDelegate.swift tho, I have to put the following code to present the first ViewController:在 SceneDelegate.swift 中,我必须放置以下代码来呈现第一个 ViewController:

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 winScene = (scene as? UIWindowScene) else { return }

    window = UIWindow(windowScene: winScene)
    window?.backgroundColor = .main
    window?.makeKeyAndVisible()
    window?.rootViewController = UINavigationController(rootViewController: ViewController())
}

This works exactly as I expected for the <13.0 iOS versions, as I marked the whole SceneDelegate.swift as available in iOS 13 only, but when I try to run this code on a 13+ iOS version, the ViewDidLoad function of my ViewController gets called twice, because I am technically instantiating it twice.这完全符合我对 <13.0 iOS 版本的预期,因为我将整个 SceneDelegate.swift 标记为仅在 iOS 13 中可用,但是当我尝试在 13+ iOS 版本上运行此代码时,我的 ViewController 的 ViewDidLoad 函数得到调用了两次,因为我在技术上将它实例化了两次。 I tried commenting out the code in the AppDelegate.swift, but that won't allow my app to be used in <13.0 iOS versions, and then I tried commenting out the code in the SceneDelegate.swift, but that won't allow my app to be used in 13+ iOS versions.我尝试注释掉 AppDelegate.swift 中的代码,但这不允许我的应用程序在 <13.0 iOS 版本中使用,然后我尝试注释掉 SceneDelegate.swift 中的代码,但这不允许我的应用程序可用于 13 多个 iOS 版本。

Is there a way to allow some piece of code to be run only In versions below 13.0?有没有办法允许某些代码仅在 13.0 以下的版本中运行? This question is not related to Nibs, xibs or any other problem mentioned in other questions about the ViewDidLoad running twice, please don't mark this as a duplicated of those ones, as it's not.这个问题与 Nibs、xibs 或关于 ViewDidLoad 运行两次的其他问题中提到的任何其他问题无关,请不要将此标记为这些问题的重复,因为它不是。

Thank you, NicopDev谢谢你,NicopDev

With ios 13 don't do anything inside didFinishLaunchingWithOptions Try使用 ios 13 不要在didFinishLaunchingWithOptions里面做任何事情试试

 if #available(iOS 13.0, *) { }
  else {
    window = UIWindow()
    window?.rootViewController = ViewController()
    window?.makeKeyAndVisible()
    window?.backgroundColor = .main
    window?.rootViewController = UINavigationController(rootViewController: ViewController())
 }

Also you need to comment either你也需要评论

window?.rootViewController = ViewController()

or或者

window?.rootViewController = UINavigationController(rootViewController: ViewController())

Yes, use #available .是的,使用#available In the AppDelegate , do the following:AppDelegate ,执行以下操作:

if #available(iOS 13, *) {
    // do nothing in AppDelegate            
} else {
    // non iOS 13 window management
}

One note here though is that you are setting the rootViewController twice: once with just ViewController (incorrect) and then later inside a UINavigationController .不过这里要注意的是,您要设置rootViewController两次:一次只使用ViewController (不正确),然后在UINavigationController You are also instantiating it twice which is unnecessary.您也将它实例化两次,这是不必要的。

For your scene delegate, mark it as:对于您的场景委托,将其标记为:

@available(iOS 13, *)
class SceneDelegate: UISceneDelegate {

}

The way I tried to fix this is the following:我试图解决这个问题的方法如下:

Inside of AppDelegate.swift AppDelegate.swift 内部

    if #available(iOS 13, *) { // Checks the current version

    } else { // If we are not in iOS 13+, then use this way of instantiating the ViewController
        window = UIWindow()
        window?.makeKeyAndVisible()
        window?.backgroundColor = .main
        window?.rootViewController = UINavigationController(rootViewController: ViewController())
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM