Reputation: 246
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.
Upvotes: 0
Views: 1235
Reputation: 535765
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)
}
Upvotes: 1
Reputation: 22375
You are misunderstanding how as
works. In 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)
}
Upvotes: 2