skip to Main Content

I want to pass viewController type as a function just like the code below

extension UIViewController {
    func switchScreen(storyboardName:String,viewControllerName:String,vcc:UIViewController) {
        let mainStoryboard = UIStoryboard(name: storyboardName, bundle: Bundle.main)
        if let viewController = mainStoryboard.instantiateViewController(withIdentifier: viewControllerName) as? vcc {
            self.present(viewController, animated: true, completion: nil)
        }
    }
}

but xcode returns an error that says Cannot find type 'vcc' in scope

I tried adding .Type in the parameter after UIViewController but the error is the same.
any solutions?

2

Answers


  1. Use generic param

    extension UIViewController {
        func switchScreen<T: UIViewController>(storyboardName:String,viewControllerName:String,vcc:T) {
            let mainStoryboard = UIStoryboard(name: storyboardName, bundle: Bundle.main)
            if let viewController = mainStoryboard.instantiateViewController(withIdentifier: viewControllerName) as? T {
                self.present(viewController, animated: true, completion: nil)
            }
        }
    }
    
    Login or Signup to reply.
  2. The third parameter must be a type, not an instance

    extension UIViewController {
        func switchScreen<T : UIViewController>(storyboardName: String, viewControllerName: String, type: T.Type) {
            let mainStoryboard = UIStoryboard(name: storyboardName, bundle: Bundle.main)
            if let viewController = mainStoryboard.instantiateViewController(withIdentifier: viewControllerName) as? T {
                self.present(viewController, animated: true, completion: nil)
            }
        }
    }
    

    and call it

    switchScreen(storyboardName: "Main", 
                 viewControllerName: "Foo", 
                 type: LoginViewController.self)
    

    But as instantiateViewController and also present don’t care about the static type you don’t need it, this is sufficient

    extension UIViewController {
        func switchScreen(storyboardName: String, viewControllerName: String) {
            let mainStoryboard = UIStoryboard(name: storyboardName, bundle: Bundle.main)
            let viewController = mainStoryboard.instantiateViewController(withIdentifier: viewControllerName)
            self.present(viewController, animated: true, completion: nil)
        }
    }
    

    To avoid a crash you could add an enum with the available view controller identifiers and pass this type in the second parameter for example

    enum ControllerIdentifier : String, RawRepresentable {
        case foo, bar
    }
    
    extension UIViewController {
        func switchScreen(storyboardName: String, viewControllerName: ControllerIdentifier) {
            let mainStoryboard = UIStoryboard(name: storyboardName, bundle: Bundle.main)
            let viewController = mainStoryboard.instantiateViewController(withIdentifier: viewControllerName.rawValue)
            self.present(viewController, animated: true, completion: nil)
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search