J'ai plusieurs contrôleurs dans mon application qui nécessitent tous une validation, et lorsque la validation échoue, je veux afficher une alerte avec les erreurs. Existe-t-il un modèle de meilleure pratique/conception pour ce faire? Je pourrais simplement créer une fonction statique dans une classe Helper comme ceci:
static func displayAlert(message: String, buttonTitle: String, vc: UIViewController)
{
let alertController = UIAlertController(title: "", message: message, preferredStyle: .Alert)
let OKAction = UIAlertAction(title: buttonTitle, style: .Default, handler: nil)
alertController.addAction(OKAction)
vc.presentViewController(alertController, animated: true, completion: nil)
}
Mais alors je dois passer le contrôleur de vue ... ce qui semble être une mauvaise pratique. Je pourrais tirer une notification et l'observer, mais cela semble exagéré. Suis-je en train de réfléchir à cela, ou y a-t-il une façon plus acceptable de gérer quelque chose comme ça?
J'ai fini par créer une extension pour UIViewController et y créer la fonction d'alerte:
extension UIViewController {
func alert(message: String, title: String = "") {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert)
let OKAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
alertController.addAction(OKAction)
self.presentViewController(alertController, animated: true, completion: nil)
}
}
Swift 4
Voilà, je le voulais donc j'ai fait une extension complète. Créez donc un nouveau fichier Swift dans votre projet, nommez-le comme vous le souhaitez à côté, placez le code suivant.
import UIKit
extension UIViewController {
func presentAlertWithTitle(title: String, message: String, options: String..., completion: @escaping (Int) -> Void) {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
for (index, option) in options.enumerated() {
alertController.addAction(UIAlertAction.init(title: option, style: .default, handler: { (action) in
completion(index)
}))
}
self.present(alertController, animated: true, completion: nil)
}
}
Ensuite, l'utiliser que tant de gens ne montrent pas réellement, ce qui peut créer de la confusion pour un débutant comme moi.
presentAlertWithTitle(title: "Test", message: "A message", options: "1", "2") { (option) in
print("option: \(option)")
switch(option) {
case 0:
print("option one")
break
case 1:
print("option two")
default:
break
}
}
Comme réponse originale de itstrueimryan à https://stackoverflow.com/a/30714429/682218
Mise à jour pour Swift 3:
extension UIViewController {
func alert(message: String, title: String = "") {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
let OKAction = UIAlertAction(title: "OK", style: .default, handler: nil)
alertController.addAction(OKAction)
self.present(alertController, animated: true, completion: nil)
}
}
J'ai peut-être trouvé une meilleure réponse à ce problème, via un article de Krakendev: https://krakendev.io/blog/subclassing-can-suck-and-heres-why .
L'idée est d'utiliser une programmation orientée protocole pour créer une implémentation par défaut d'une alerte uniquement pour UIViewControllers:
protocol Alertable {
func issueAlert()
}
extension Alertable where Self: UIViewController {
func issueAlert() {
// alert code here
}
}
Maintenant, juste comme ça, chaque UIViewController qui adhère à Alertable aura la méthode issueAlert () à sa disposition sans même avoir à définir sa propre implémentation.
Et, bien sûr, nous pouvons également définir des paramètres pour la fonction issueAlert:
extension Alertable where Self: UIViewController {
func issueAlert(title: "Default Title", message: String = "Default Message") {
// alert code here
}
}
Notre contrôleur de vue peut donc:
issueAlert()
ou
issueAlert(title: "Error", message: "Something went wrong")
Je peux penser à deux avantages de cette approche: vous savez si un contrôleur de vue a accès à cette méthode simplement en regardant le protocole Alertable dans la définition de classe, et les contrôleurs de vue individuels peuvent remplacer cette méthode s'ils souhaitent fournir des fonctionnalités personnalisées . Bien sûr, vous pouvez désormais également spécifier le contrat Alertable comme paramètre de méthode.
Pourquoi ne pas créer une fonction utilitaire qui renvoie AlertView au ViewController?
self.presentViewController(Utilities.createAlertController("errorMessage"), animated: true, completion: nil);
Mis à jour pour Swift 3:
si vous souhaitez afficher le message d'alerte à l'utilisateur utilisé ci-dessous de simples lignes de code;
// définition de fonction:
func showMessageToUser(title: String, msg: String) {
let alert = UIAlertController(title: title, message: msg, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
// appel de fonction:
self.showMessageToUser(title: "Alert", msg: "your message to user")
// Profitez du codage ..!