Motoko
Motoko

Reputation: 3

How to create a generic function to load a view controller?

I have been trying to write a function that works with 3 parameters in order to load a view controller but I haven't been able to make it work.

I'm new into coding and I am reading a tutorial that uses 2 view controllers (login & chat). In order to go from one to the other, the guide tells me to use this whether I want to log in or log out:

@IBAction func loginDidTapped(_ sender: Any) {

    // A
    let storyboard = UIStoryboard (name: "Main", bundle: nil)   
    // B
    let logVC = storyboard.instantiateViewController(withIdentifier: "LoginVC") as! LoginViewController   
    // C
    let appDelegate = UIApplication.shared.delegate as! AppDelegate   
    // D
    appDelegate.window?.rootViewController = logVC        
}

If I want to log in or log out I have to change 3 things:

  1. logVC , which I'd call var1, used in // B , // D
  2. "LoginVC" , which I'd call var2, used in // B
  3. LoginViewController , which I'd call var3, used in // B

In my newb mind, I imagined that I could create a function that contained the "A, B, C, D" lines and let me call it anywhere later just by changing "var1, var2, var3" parameters


This is what I first created using just var1 and var2:

import Foundation
import UIKit
import FirebaseAuth

    class Helper {
        static let helper = Helper()

        func loadView (var1 : String , var2 : String) {

            let storyboard = UIStoryboard (name: "Main", bundle: nil)
            let var1 = storyboard.instantiateViewController(withIdentifier: var2) as! LoginViewController
            let appDelegate = UIApplication.shared.delegate as! AppDelegate
            appDelegate.window?.rootViewController = var1
         }
    }

I called it this way and it worked:

Helper.helper.loadView(var1: "logVC" , var2: "LoginVC")

Now, when I tried to use var3 in line //B, inside the same function, Xcode underlines var3 and displays this error:

Use of undeclared type 'var3'

This is how it looked after adding a the var3 parameter:

    func loadView (var1 : String , var2 : String , var3 : String) {

                    let storyboard = UIStoryboard (name: "Main", bundle: nil)
                    let var1 = storyboard.instantiateViewController(withIdentifier: var2) as! var3
                    let appDelegate = UIApplication.shared.delegate as! AppDelegate
                    appDelegate.window?.rootViewController = var1
}

This is how I would have called it if it had worked:

Helper.helper.loadView(var1: "logVC" , var2: "LoginVC" , var3: "LoginViewController")

I'd like to know if is it possible to do what I am imaging since I see functions as equations in which I can replace variables with the information I need.

Thank you all in advance.

Upvotes: 0

Views: 576

Answers (1)

Sweeper
Sweeper

Reputation: 273258

You are overthinking. Do you really need 3 variables?

Actually, you just need one.

Let's see why.

Does the name of the variable really matter in B? Does the LoginViewController at the end of B really need to be there? No. The variable name is just a variable name. Changing it changes nothing about your code. It might make your code more readable though. The same goes for the LoginViewController as the end. That just causes var1 to be of type LoginViewController. But this is unnecessary because you are assigning it to rootViewController later anyway. rootViewController is of type UIViewController, so you can just pass any variable of type UIViewController. To learn more about this behaviour, look up polymorphism.

Thus, your method is just this:

func presentVC(name: String) {

    let storyboard = UIStoryboard (name: "Main", bundle: nil)
    let vc = storyboard.instantiateViewController(withIdentifier: name)
    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    appDelegate.window?.rootViewController = vc
}

Upvotes: 1

Related Questions