Reputation: 999
Basically I am currently adding functionX
to everywhere i present an UIAlertController as seen below:
let alert = UIAlertController(title: "", message: "", preferredStyle: .alert)
let okAction = UIAlertAction(title: "ok", style: .default)
alert.addAction(okAction)
functionX(actionSheet: alert, controller: self)
self.present(alert, animated: true, completion: nil)
// or it can be
// tableviewController.present(alert, animated: true, completion: nil)
Instead of calling functionX
every time, I want to override a present method and call functionX
there. I attempted the following:
extension UIViewController {
override func present(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)? = nil) {
if (viewControllerToPresent is UIAlertController) {
functionX(actionSheet: viewControllerToPresent, controller: /* what should this be? */ )
}
super.present() //error here
}
}
Is this an appropriate approach? Can you help me fill the missing parameters?
i.e.:
What should be the controller? What would self
or tableviewController
from the first code stub be in the overriding present function?
How should I call the present
method in the overriding present function?
Upvotes: 0
Views: 904
Reputation: 2823
Overrides of NSObject's derivatives in Swift's static extensions is only for Objective-C compatibility. You cannot override
in extensions of pure Swift declarations. Think of it in such manner that if the class itself adds an override, and then a static extension adds an override. Which implementation should the linker link? And which implementation does super
call refer to? In Objective-C this behavior is undefined, in Swift the extension override is ignored all together.
What you could do instead is move the overriding function from the extension directly to the class.
Upvotes: 0
Reputation: 275085
According to the Swift guide,
Extensions can add new functionality to a type, but they cannot override existing functionality.
So you shouldn't really be overriding an existing method in a UIViewController
in an extension.
What you could do is, to add your own present
, called functionXAndPresent
:
extension UIViewController {
func functionXAndPresent(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)? = nil) {
if (viewControllerToPresent is UIAlertController) {
// to answer your second question, you should use "self" here
functionX(actionSheet: viewControllerToPresent, controller: self)
}
present(viewControllerToPresent, animated: flag, completion: completion)
}
}
You can't do this by overriding because as you have found out, you can't really refer to the "non-overridden" method at the end. super.present
doesn't work because you are in an extension, not a subclass.
Upvotes: 4
Reputation: 24341
You can simply create a common method showAlert(with:and:)
in a UIViewController
extension
and call functionX
when the alert
is presented, i.e.
extension UIViewController {
func showAlert(with title: String?, message: String?) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: .default)
alert.addAction(okAction)
self.present(alert, animated: true, completion: {
self.functionX(actionSheet: alert, controller: self)
})
}
func functionX(actionSheet: UIAlertController, controller: UIViewController) {
//your code here...
}
}
Usage:
Call the showAlert(with:and:)
method from whatever controller you want to, be it a UIViewController
or a UITableViewController
or any other, i.e
self.showAlert(with: "Alery..!!!", message: "This is a sample alert.")
Upvotes: 1