I am developing in Swift 2.3
I have an Utils class enabling me to create UIAlertController easily.
public class Utils {
class func buildAlertInfo(withTitle title: String?, andMessage message: String?, withHandler handler: (UIAlertAction -> Void)?) -> UIAlertController {
let alertController = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: handler))
return alertController
}
}
It enables me to build AlertController with ease :
let alert = Utils.buildAlertInfo(withTitle: "Information", andMessage: "John Snow is dying", withHandler: nil)
self.presentViewController(alert, animated: false, completion: nil)
My issue now is that I want to create an other type of custom Alert in my Utils Class. For example an Alert with a Button that navigates the user to a specific ViewController.
I don't know how can I access a ViewController in a Custom Class. Maybe pass as a parameter the ViewController I want to present after the Button is tapped ?
Should I respect the MVC pattern and not interact with the View in my Utils Class ?
EDIT :
The Alert I want should looks like this :
class func buildAlertInfoWithFavButton(withTitle title: String?, andMessage message: String?, withHandler handler: (UIAlertAction -> Void)?) -> UIAlertController {
let alertController = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: handler))
alertController.addAction(UIAlertAction(title: "Favorite", style: UIAlertActionStyle.Default, handler: handler))
return alertController
}
Where the OK action is the same, but the Favorite action should navigates you to the FavoriteViewController.
You can still use your buildAlertInfo
function and can pass handler function like this way.
//Add function in your controller
func handler(action: UIAlertAction) {
//Add code of present
}
Now pass this function with your handler block
let alert = Utils.buildAlertInfo(withTitle: "Information",
andMessage: "John Snow is dying",
withHandler: self.handler)
**Edit:**For multiple action you can create array of handler with your method like this.
func buildAlertInfoWithFavButton(withTitle title: String?, andMessage message: String?, withHandler handler: [((UIAlertAction) -> Void)]?) -> UIAlertController {
alertController.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: handler.first))
alertController.addAction(UIAlertAction(title: "Favorite", style: UIAlertActionStyle.Default, handler: handler.last))
}
//Ok handler
func okHandler(action: UIAlertAction) {
//Add code of present
}
//Favorite handler
func favoriteHandler(action: UIAlertAction) {
//Add code of present
}
Now call the function like this.
let alert = Utils.buildAlertInfo(withTitle: "Information",
andMessage: "John Snow is dying",
withHandler: [okHandler, favoriteHandler])
What about
let alert = Utils.buildAlertInfo(
withTitle: "Information",
andMessage: "John Snow is dying",
withHandler: { action in self.go(to: specificViewController) }
)
self.presentViewController(alert, animated: false, completion: nil)
?
To be more Specific and use that method in any class of project. For this make a function in NSObject class. Like:
open class func showAlert(_ delegate: UIViewController, message: String ,strtitle: String, handler:((UIAlertAction) -> Void)! = nil)
{
let alert = UIAlertController(title: strtitle, message: message, preferredStyle: UIAlertControllerStyle.alert)
if handler == nil{
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
}
else
{
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: handler))
}
delegate.present(alert, animated: true, completion: nil)
}
In Controller I will call the method and do the required work like:
Alert.showAlert(self, message: "Message", strtitle: "Tittle!!", handler: {
(action : UIAlertAction) in
//Do your Work here
})
Note: Here Alert is name of NSObject class.
I would suggest using segue identifiers as the passed parameter (make sure you reference a segue that starts in the ViewController you call the "buildAlert" function from).
public class Utils {
class func buildAlertInfo(withTitle title: String?, andMessage message: String?, withSegue segueIdentifier: String?, sender: Any?) -> UIAlertController {
let alertController = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(UIAlertAction(title: "OK", style: .Default, handler: handler: {
action in
self.performSegue(withIdentifier: segueIdentifier, sender: sender)
})
return alertController
}
This can also be achieved without creating a new function, just sending the handler part from above as a parameter to the function you already have, like this:
let alert = Utils.buildAlertInfo(withTitle: "Information", andMessage: "John Snow is dying", withHandler: {
action in
self.performSegue(withIdentifier: "mySegueIdentifier", sender: self)
})
EDIT: Note that the sender part can be any object that has an @IBOutlet reference in the ViewController the function call takes place
来源:https://stackoverflow.com/questions/41588882/swift-how-to-present-viewcontroller-when-tapping-button-in-a-custom-alertcontr