简体   繁体   中英

Avoid initializing the same storyboard again

configureViewController() method is called every time each ViewControllers viewWillAppear() methods gets called; therefore, I am wondering how to avoid multiple places initializing the same viewcontroller of the same storyboard .

What would be the best approach in this scenario?

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

Hope I get what you mean correctly.

I would suggest to create a property to store the viewController , return it if it already existed, or create one when it's not.

For example:

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

Update:

If we want to avoid initializing UIStoryboard again and again, we can just store the UIStoryboard using the same idea.

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

therefore, I am wondering how to avoid multiple places initializing the same viewcontroller of the same storyboard.

I am a bit confused about "to avoid initializing the same viewController of the same storyboard", but if you mean "Ensuring that we create a new loginVC instead of using the old one / existing one because we want user to go back to the entry point and login", then you can see from the print statement that the loginVC() is a brand new one.

Additional: The above answer is based on iOS version less than 13.0. In iOS13.0+, the handling of UIWindow is recommended to move to SceneDelegate.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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