简体   繁体   中英

How to pass viewcontroller name in function parameters?

func showalertOkayButton(message: String?, identifier: string?, viewControllerName: UIViewController){

    let alertController = UIAlertController(title: kMessage, message: message, preferredStyle: .alert)
       let defaultaction = UIAlertAction(title: kOkay, style: UIAlertAction.Style.default, handler:{ defaultaction in
        let VC = UIStoryboard(name: kMainStoryBoard, bundle: nil).instantiateViewController(withIdentifier: identifier) as! viewControllerName
        self.navigationController?.pushViewController(VC, animated: true)
    })
    alertController.addAction(defaultaction)
    present(alertController, animated: true, completion: nil)
}

so my question is i can't send the viewControllerName it's giving me error "used of undeclared" so how can i send the view controller name in function. well this is for learning purpose sorry if i asking wrong thing. so please guide me or help me Thank in advacne.

You are misunderstanding how as works. In x as! y x as! y , y is not a name it is a type . And when you have viewControllerName: UIViewController as a function parameter, that is not passing a name that is passing an instance of the UIViewController type . So if you want to specify what that as is casting to, you need to pass a type as your function parameter. Using generics, that looks like this:

func showalertOkayButton<T: UIViewController>(message: String?, identifier: String, viewControllerType: T.Type) {
    let alertController = UIAlertController(title: kMessage, message: message, preferredStyle: .alert)

    let defaultaction = UIAlertAction(title: kOkay, style: UIAlertAction.Style.default, handler:{ defaultaction in
        let VC = UIStoryboard(name: kMainStoryBoard, bundle: nil).instantiateViewController(withIdentifier: identifier) as! T
        self.navigationController?.pushViewController(VC, animated: true)
    })

    alertController.addAction(defaultaction)
    present(alertController, animated: true, completion: nil)
}

Calling it would look like this

showalertOkayButton("Message", "VCIdentifier", MyViewController.self)

However, none of this is necessary in your specific case. Swift is a dynamic language, so when you instantiate a view controller from a storyboard it can load its dynamic type information at runtime. However the compiler doesn't know what type it is so it gives you a simple UIViewController instance as a result. It is not necessary to cast it using as until the moment you need to call specific methods on that view controller that don't exist in the UIViewController superclass.

Even if you don't cast it, it will continue to behave correctly thanks to polymorphism. So you can shorten your code to this

func showalertOkayButton(message: String?, identifier: String) {
    let alertController = UIAlertController(title: kMessage, message: message, preferredStyle: .alert)

    let defaultaction = UIAlertAction(title: kOkay, style: UIAlertAction.Style.default, handler:{ defaultaction in
        let VC = UIStoryboard(name: kMainStoryBoard, bundle: nil).instantiateViewController(withIdentifier: identifier)
        self.navigationController?.pushViewController(VC, animated: true)
    })

    alertController.addAction(defaultaction)
    present(alertController, animated: true, completion: nil)
}

Swift is static, not dynamic. All types have to be known in advance. You cannot pass an unknown type and say “cast to this type” at runtime. But you don't need to. Just strip out the stuff about the view controller "name" (actually its class). You can push a view controller without knowing its specific class, It's a view controller. The compiler knows that, and that's all it needs to know. Just delete your stuff about the view controller's type, and all will be well.

func showalertOkayButton(message: String?, identifier: String)
    let alertController = UIAlertController(title: kMessage, message: message, preferredStyle: .alert)
    let defaultaction = UIAlertAction(title: kOkay, style: UIAlertAction.Style.default, handler:{ defaultaction in
        let VC = UIStoryboard(name: kMainStoryBoard, bundle: nil).instantiateViewController(withIdentifier: identifier)
        self.navigationController?.pushViewController(VC, animated: true)
    })
    alertController.addAction(defaultaction)
    present(alertController, animated: true, completion: nil)
}

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