ViewDidLoad被两次调用iOS 13 +

问题描述 投票:0回答:3

[我正在开发适用于iOS 12+的应用,并且iOS 13需要SceneDelegate的事实在以编程方式显示第一个ViewController时使我遇到了一些问题,因为我不使用故事板。

在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
}

这对于那些设备正常工作;在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())
}

这完全符合我对<13.0 iOS版本的预期,因为我将整个SceneDelegate.swift标记为仅在iOS 13中可用,但是当我尝试在13+ iOS版本上运行此代码时,我的ViewDidLoad函数ViewController被调用两次,因为我在技术上实例化了两次。我尝试注释掉AppDelegate.swift中的代码,但是不允许我的应用程序在<13.0 iOS版本中使用,然后尝试注释掉SceneDelegate.swift中的代码,但是不允许我的应用程序应用程序可在13个以上的iOS版本中使用。

是否有一种方法可以只允许在13.0以下的版本中运行某些代码?此问题与Nib,xib或其他关于ViewDidLoad运行两次的其他问题中提到的其他问题无关,请不要将其标记为重复的那些,因为不是。

谢谢你,NicopDev

ios swift viewcontroller ios13 viewdidload
3个回答
2
投票

使用ios 13,请勿在didFinishLaunchingWithOptions内部执行任何操作

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

也您需要发表评论

window?.rootViewController = ViewController()

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

0
投票

我尝试解决此问题的方法如下:

在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())
    }

0
投票

是,请使用#available。在AppDelegate中,执行以下操作:

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

不过这里要注意的是,您要设置两次rootViewController:一次仅使用ViewController(不正确),然后再在UINavigationController内部。您还将实例化两次,这是不必要的。

对于您的场景代表,将其标记为:

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

}
© www.soinside.com 2019 - 2024. All rights reserved.