Search code examples
iosswift

Swift: how to load view controllers sequentially?


I want to load first view controller programatically and load second view controller next automatically from first. I use this code:

SceneDelegate:

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

SLLoadingViewController:

override func viewDidLoad() {
    super.viewDidLoad()
    load()
}

func load() {
    
    let nav = SLNavigationViewController()
    let mainView = StoreViewController()
    nav.navigationBar.frame.size = nav.navigationBar.sizeThatFits(CGSize(width: nav.navigationBar.frame.size.width, height: 2))
    nav.viewControllers = [mainView]
    
    present(nav, animated: false, completion: nil)
}

But this doesn't work. Last controller not showing on screen. If I use next code all works fine:

override func viewDidLoad() {
    super.viewDidLoad()
    button.frame = CGRect(x: 100, y: 200, width: 30, height: 20)
    button.backgroundColor = .green
    view.addSubview(button)
    button.addTarget(self, action: #selector(self.load), for: .touchUpInside) 
}

@objc func load() {
    
    let nav = SLNavigationViewController()
    let mainView = StoreViewController()
    nav.navigationBar.frame.size = nav.navigationBar.sizeThatFits(CGSize(width: nav.navigationBar.frame.size.width, height: 2))
    nav.viewControllers = [mainView]
    
    present(nav, animated: false, completion: nil)
}

But In this case I use a button. How to load last view controller from first without button tap?


Solution

  • Swift: how to load view controllers sequentially?

    AFAICT, this isn't a question about Swift at all. The problem you're having would likely be exactly the same if the code were written in Objective-C.

    override func viewDidLoad() {
        super.viewDidLoad()
        load()
    }
    

    It's a little weird that a function called load is called from viewDidLoad. Choosing a less confusing name might lead to less confusion.

    let mainView = StoreViewController()
    nav.navigationBar.frame.size = nav.navigationBar.sizeThatFits(CGSize(width: nav.navigationBar.frame.size.width, height: 2))
    nav.viewControllers = [mainView]
    

    I can't remember ever needing or wanting to directly set the navigation controller's array of view controllers. Why do you think you need to do that? I see that you're using some sort of custom navigation controller, but it's not clear why you need that, or why you need to load things in such a convoluted way. Why not just use a regular nav controller and make StoreViewController the nav controller's root view controller?