首页 > 解决方案 > 避免再次初始化相同的故事板

问题描述

configureViewController()每次调用每个 ViewControllersviewWillAppear()方法时都会调用该方法;因此,我想知道如何避免多个地方初始化相同viewcontroller的相同storyboard

在这种情况下,最好的方法是什么?

AppDelegate.swift

private func loginVC() -> UIViewController {
  let storyboard = UIStoryboard(name: "Main", bundle: nil)
  return storyboard.instantiateViewController(withIdentifier: "LoginVC")
}
  
private func homeVC() -> UIViewController {
  let storyboard = UIStoryboard(name: "Main", bundle: nil)
  return storyboard.instantiateViewController(withIdentifier: "HomeVC")
}
  
public func configureViewController() {
  if isLoginRequired() {
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let navigationController = storyboard.instantiateInitialViewController() as! UINavigationController
    navigationController.viewControllers = [loginVC()]
    keyWindow?.rootViewController = navigationController
  }
}

标签: iosswift

解决方案


希望我能正确理解你的意思。

我建议创建一个属性来存储viewController,如果它已经存在则返回它,或者在它不存在时创建一个。

例如:

var nav: UINavigationController?

public func configureViewController() {
  if isLoginRequired() {
    if let nav = self.nav {
        keyWindow?.rootViewController = nav
    } else {
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let navigationController = storyboard.instantiateInitialViewController() 
as! UINavigationController
        navigationController.viewControllers = [loginVC()]
        nav = navigationController
        keyWindow?.rootViewController = navigationController
      }
    }
}

更新:

如果我们想避免一次又一次地初始化 UIStoryboard,我们可以使用相同的想法存储 UIStoryboard。

AppDelegate.swift

var keyWindow: UIWindow?
let storyboard = UIStoryboard(name: "Main", bundle: nil)

private func loginVC() -> UIViewController {
    return storyboard.instantiateViewController(withIdentifier: "LoginVC")
}

private func homeVC() -> UIViewController {
    return storyboard.instantiateViewController(withIdentifier: "HomeVC")
}

public func configureViewController() {
    if isLoginRequired() {
        let navigationController = storyboard.instantiateInitialViewController() as! UINavigationController
        // replace the viewControllers in navigationControllers with a whole new stack
        // initialize a new loginVC and put it in the stack
        navigationController.viewControllers = [loginVC()]
        // you can print and check the memory address of the viewController in the navigationController
        print(navigationController.viewControllers) 
        keyWindow?.rootViewController = navigationController
        keyWindow?.makeKeyAndVisible()
    }
}

因此,我想知道如何避免多个地方初始化同一个故事板的同一个视图控制器。

我对“避免初始化同一个故事板的同一个 viewController”有点困惑,但是如果你的意思是“确保我们创建一个新的 loginVC 而不是使用旧的 / 现有的,因为我们希望用户回到条目点并登录”,然后您可以从打印声明中看到这loginVC()是一个全新的。

附加: 以上答案基于低于 13.0 的 iOS 版本。在iOS13.0+中,UIWindow的处理建议移到SceneDelegate。


推荐阅读