Home > Blockchain >  passing viewController as a parameter in function
passing viewController as a parameter in function

Time:01-16

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?

CodePudding user response:

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

CodePudding user response:

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)
        }
    }
}
  • Related