ios swift uitextfield uialertview

ios - ¿Cómo validar TextFields en un UIAlertController?



swift uitextfield (10)

Esto se puede hacer extendiendo UIAlertViewController :

extension UIAlertController { func isValidEmail(_ email: String) -> Bool { return email.characters.count > 0 && NSPredicate(format: "self matches %@", "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+//.[a-zA-Z]{2,64}").evaluate(with: email) } func isValidPassword(_ password: String) -> Bool { return password.characters.count > 4 && password.rangeOfCharacter(from: .whitespacesAndNewlines) == nil } func textDidChangeInLoginAlert() { if let email = textFields?[0].text, let password = textFields?[1].text, let action = actions.last { action.isEnabled = isValidEmail(email) && isValidPassword(password) } } } // ViewController override func viewDidLoad() { super.viewDidLoad() let alert = UIAlertController(title: "Please Log In", message: nil, preferredStyle: .alert) alert.addTextField { $0.placeholder = "Email" $0.addTarget(alert, action: #selector(alert.textDidChangeInLoginAlert), for: .editingChanged) } alert.addTextField { $0.placeholder = "Password" $0.isSecureTextEntry = true $0.addTarget(alert, action: #selector(alert. textDidChangeInLoginAlert), for: .editingChanged) } alert.addAction(UIAlertAction(title: "Cancel", style: .cancel)) let loginAction = UIAlertAction(title: "Submit", style: .default) { [unowned self] _ in guard let email = alert.textFields?[0].text, let password = alert.textFields?[1].text else { return } // Should never happen // Perform login action } loginAction.isEnabled = false alert.addAction(loginAction) present(alert, animated: true) }

¿Alguien puede decirme cómo validar los UITextFields de UIAlertController UITextFields dentro de un UIAlertController ?

Lo necesito para evitar que el usuario haga clic en "Guardar" a menos que se ingresen ambos campos.

Aquí está mi código hasta ahora:

@IBAction func btnStart(sender: AnyObject) { var alert = UIAlertController(title: "New user", message: "Add a new user", preferredStyle: .Alert) let saveAction = UIAlertAction(title: "Save", style: .Default) { (action: UIAlertAction!) -> Void in self.textFieldName = alert.textFields![0] as UITextField self.textFieldEmail = alert.textFields![1] as UITextField self.saveUser(self.textFieldName.text, email: self.textFieldEmail.text) self.tableView.reloadData() } saveAction.enabled = false let cancelAction = UIAlertAction(title: "Cancel", style: .Default) { (action: UIAlertAction!) -> Void in } alert.addTextFieldWithConfigurationHandler { (textFieldName: UITextField!) in textFieldName.placeholder = "Enter full name" } alert.addTextFieldWithConfigurationHandler { (textFieldEmail: UITextField!) in textFieldEmail.placeholder = "Enter valid email adress" textFieldEmail.keyboardType = .EmailAddress } alert.addAction(saveAction) alert.addAction(cancelAction) presentViewController(alert, animated: true, completion: nil) }

Esta es mi función para validar el campo de correo electrónico:

func isValidEmail(testStr:String) -> Bool { let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+//.[A-Za-z]{2,4}" if let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx) { return emailTest.evaluateWithObject(testStr) } return false }


Esto se puede lograr a través de NSNotificationCenter antes de mostrar el controlador de alerta; todo lo que tiene que hacer es pedirle al centro de notificaciones que observe la notificación de UITextFieldTextDidChangeNotification y debería estar en buen estado,

A continuación se detalla la implementación de la misma.

@IBAction func showAlert(sender: AnyObject) { var alert = UIAlertController(title: "New user", message: "Add a new user", preferredStyle: .Alert) let saveAction = UIAlertAction(title: "Save", style: .Default) { (action: UIAlertAction!) -> Void in println("do your stuff here") } saveAction.enabled = false let cancelAction = UIAlertAction(title: "Cancel", style: .Default) { (action: UIAlertAction!) -> Void in } alert.addTextFieldWithConfigurationHandler { (textFieldName: UITextField!) in textFieldName.placeholder = "Enter full name" } alert.addTextFieldWithConfigurationHandler { (textFieldEmail: UITextField!) in textFieldEmail.placeholder = "Enter valid email adress" textFieldEmail.keyboardType = .EmailAddress } // adding the notification observer here NSNotificationCenter.defaultCenter().addObserverForName(UITextFieldTextDidChangeNotification, object:alert.textFields?[0], queue: NSOperationQueue.mainQueue()) { (notification) -> Void in let textFieldName = alert.textFields?[0] as! UITextField let textFieldEmail = alert.textFields![1] as! UITextField saveAction.enabled = self.isValidEmail(textFieldEmail.text) && !textFieldName.text.isEmpty } NSNotificationCenter.defaultCenter().addObserverForName(UITextFieldTextDidChangeNotification, object:alert.textFields?[1], queue: NSOperationQueue.mainQueue()) { (notification) -> Void in let textFieldEmail = alert.textFields?[1] as! UITextField let textFieldName = alert.textFields?[0] as! UITextField saveAction.enabled = self.isValidEmail(textFieldEmail.text) && !textFieldName.text.isEmpty } alert.addAction(saveAction) alert.addAction(cancelAction) presentViewController(alert, animated: true, completion: nil) } // email validation code method func isValidEmail(testStr:String) -> Bool { let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+//.[A-Za-z]{2,4}" if let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx) as NSPredicate? { return emailTest.evaluateWithObject(testStr) } return false }


Implementé una subclase UIAlertController que le permite agregar un controlador en los cambios de campo de texto cuando lo agrega a la alerta:

public class TextEnabledAlertController: UIAlertController { private var textFieldActions = [UITextField: ((UITextField)->Void)]() func addTextField(configurationHandler: ((UITextField) -> Void)? = nil, textChangeAction:((UITextField)->Void)?) { super.addTextField(configurationHandler: { (textField) in configurationHandler?(textField) if let textChangeAction = textChangeAction { self.textFieldActions[textField] = textChangeAction textField.addTarget(self, action: #selector(self.textFieldChanged), for: .editingChanged) } }) } @objc private func textFieldChanged(sender: UITextField) { if let textChangeAction = textFieldActions[sender] { textChangeAction(sender) } } }

Entonces, para su caso, lo único que debe agregarse es llamar a la función isValidEmail en el controlador textChangeAction:

alert.addTextField(configurationHandler: { (textField) in // things you want to configure on the textfield }) { (textField) in saveAction.isEnabled = isValidEmail(textField.text ?? "") }


La forma más elegante es usar

NotificationCenter.default.addObserver(forName: NSNotification.Name.UITextFieldTextDidChange...

Ejemplo de Swift 3.0

let alert = UIAlertController(title: nil, message: nil, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) let saveAction = UIAlertAction(title:"Save", style: .destructive, handler: { (action) -> Void in }) alert.addAction(saveAction) alert.addTextField(configurationHandler: { (textField) in textField.placeholder = "Enter something" NotificationCenter.default.addObserver(forName: NSNotification.Name.UITextFieldTextDidChange, object: textField, queue: OperationQueue.main) { (notification) in saveAction.isEnabled = textField.text!.length > 0 } }) present(alert, animated: true, completion: nil)


Primero, necesitas agregar algunas variables a tu clase:

private weak var saveAction : UIAlertAction? private weak var textFieldName : UITextField? private weak var textFieldEmail : UITextField? private var validName = false private var validEmail = false

Luego, cuando desee configurar el controlador de alerta (solo pegué las cosas que deben cambiarse):

alert.addTextFieldWithConfigurationHandler { (textFieldName: UITextField!) in textFieldName.placeholder = "Enter full name" textFieldName.delegate = self self.textFieldName = textFieldName } alert.addTextFieldWithConfigurationHandler { (textFieldEmail: UITextField!) in textFieldEmail.placeholder = "Enter valid email adress" textFieldEmail.keyboardType = .EmailAddress textFieldEmail.delegate = self self.textFieldEmail = textFieldEmail } let saveAction = UIAlertAction(title: "Save", style: .Default) { (action: UIAlertAction!) -> Void in // here you are sure the name and email are correct let name = (alert.textFields[0] as! UITextField).text let email = (alert.textFields[1] as! UITextField).text } saveAction.enabled = false self.saveAction = saveAction

Finalmente, deberías implementar este método de delegado:

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { let newText = NSString(string: textField.text).stringByReplacingCharactersInRange(range, withString: string) if textField == self.textFieldName { // validate newText for the name requirements validName = self.validateName(newText) } else if textField == self.textFieldEmail { // validate newText for the email requirements validEmail = self.validateEmail(newText) } self.saveAction?.enabled = validEmail && validName return true }


Puede usar el siguiente código para validar TextFields en un UIAlertController: -

Paso 1:

Declare "email_TF" to your viewcontroller.h for example: @property(strong,nonatomic)UITextField *email_TF;

Paso 2:

UIAlertController *alert= [UIAlertController alertControllerWithTitle:@"Forgot Password?" message:nil preferredStyle:UIAlertControllerStyleAlert]; [alert addTextFieldWithConfigurationHandler: ^(UITextField *textField){ textField.placeholder= @"Enter Your Valid Email"; textField.autocorrectionType= UITextAutocorrectionTypeYes; textField.keyboardType= UIKeyboardTypeEmailAddress; email_TF= textField; }];

Paso 3:

UIAlertAction *noButton= [UIAlertAction actionWithTitle:@"No, thanks" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action){ //Handel no, thanks button }]; [alert addAction:noButton]; UIAlertAction *yesButton= [UIAlertAction actionWithTitle:@"Yes, please" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){ //Handel your yes please button action here NSLog(@"%@", email_TF.text); if(email_TF.text.length>0){// NSString *emailString= email_TF.text; NSString *emailReg= @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+//.[A-Za-z]{2,4}"; NSPredicate *emailTest= [NSPredicate predicateWithFormat:@"SELF MATCHES %@",emailReg]; if(([emailTest evaluateWithObject:emailString]!=YES) || [emailString isEqualToString:@""]){ UIAlertView *loginalert= [[UIAlertView alloc] initWithTitle:@"Forgot Password !" message:@"/nPlease enter valid Email ([email protected] format) ." delegate:self cancelButtonTitle:@"Ok" otherButtonTitles: nil]; [loginalert show]; }else{ NSLog(@"your TextField successfully validated"); } }else{ UIAlertView *alert= [[UIAlertView alloc] initWithTitle:@"Forgot Password !" message:@"/nPlease Enter Your Email..." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; } }]; [alert addAction:yesButton];

Etapa 4:

[self presentViewController:alert animated:YES completion:nil];


Regístrese para recibir notificaciones de cambio de campo de texto y valide los campos de texto allí

//... alert.addTextFieldWithConfigurationHandler { (textFieldEmail: UITextField!) in textFieldEmail.placeholder = "Enter valid email adress" textFieldEmail.keyboardType = .EmailAddress } let textFieldValidationObserver: (NSNotification!) -> Void = { _ in let textFieldName = alert.textFields![0] as! UITextField let textFieldEmail = alert.textFields![1] as! UITextField saveAction.enabled = self.isValidEmail(textFieldEmail.text) && textFieldName.text.length > 0 } // Notifications for textFieldName changes NSNotificationCenter.defaultCenter().addObserverForName(UITextFieldTextDidChangeNotification, object: alert.textFields![0], // textFieldName queue: NSOperationQueue.mainQueue(), usingBlock: textFieldValidationObserver) // Notifications for textFieldEmail changes NSNotificationCenter.defaultCenter().addObserverForName(UITextFieldTextDidChangeNotification, object: alert.textFields![1], // textFieldEmail queue: NSOperationQueue.mainQueue(), usingBlock: textFieldValidationObserver) alert.addAction(saveAction) //...


Siguiendo lo que @Kupendiran presentó para la validación de entrada de correo electrónico con UIAlertController. Aquí hay una versión que funciona con Objective-C y el nuevo formato UIAlertController como UIAlertView ahora está depreciado.

Paso 1. agregue lo siguiente a los archivos .h y .m con otras propiedades y variables

.h

@property(strong,nonatomic)UITextField *emailAddressField;

.metro

UITextField *emailAddressField;

Paso 2. Crea el mensaje de alerta, botones y proceso de validación.

UIAlertController * alertView = [UIAlertController alertControllerWithTitle:@"E-Mail Address" message:@"Enter your email address:" preferredStyle:UIAlertControllerStyleAlert]; [alertView addTextFieldWithConfigurationHandler:^(UITextField *emailTextField) { emailTextField.placeholder = @"E-Mail Address"; emailTextField.autocorrectionType= UITextAutocorrectionTypeYes; emailTextField.keyboardType= UIKeyboardTypeEmailAddress; emailAddressField = emailTextField; }];

Paso 3. Crea las acciones de alerta.

UIAlertAction * ok= [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){ //Handel your OK button action here NSLog(@"Email Address Entered is: %@", emailAddressField.text); //Validate email address is correct format if(emailAddressField.text.length>0){// NSString *emailString= emailAddressField.text; NSString *emailReg= @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+//.[A-Za-z]{2,4}"; NSPredicate *emailTest= [NSPredicate predicateWithFormat:@"SELF MATCHES %@",emailReg]; if(([emailTest evaluateWithObject:emailString]!=YES) || [emailString isEqualToString:@""]){ NSLog(@"Email Address Entered is not valid: %@", emailAddressField.text); UIAlertController *badEmailAlert = [UIAlertController alertControllerWithTitle:@"Email Address" message:@"/nPlease enter valid Email ([email protected] format) ." preferredStyle:UIAlertControllerStyleAlert]; [self presentViewController:badEmailAlert animated:YES completion:nil]; UIAlertAction* cancel = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { [badEmailAlert dismissViewControllerAnimated:YES completion:nil]; [self presentViewController:alertView animated:YES completion:nil]; }]; [badEmailAlert addAction:cancel]; }else{ NSLog(@"your TextField successfully validated"); } }else{ [self presentViewController:alertView animated:YES completion:nil]; } }]; [alertView addAction:ok]; //Handel your Cancel button action here UIAlertAction* cancel = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { [alertView dismissViewControllerAnimated:YES completion:nil]; }]; [alertView addAction:cancel];

Paso 4. Presentar el mensaje de alerta en la pantalla.

[self presentViewController:alertView animated:YES completion:nil];


Para la actualización Swift 4.2 (NSNotification.Name.UITextFieldTextDidChange):

let alert = UIAlertController(title: nil, message: nil, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) let saveAction = UIAlertAction(title:"Save", style: .destructive, handler: { (action) -> Void in }) alert.addAction(saveAction) alert.addTextField(configurationHandler: { (textField) in textField.placeholder = "Enter something" NotificationCenter.default.addObserver(forName: UITextField.textDidChangeNotification, object: textField, queue: OperationQueue.main) { (notification) in saveAction.isEnabled = textField.text?.count > 0 } }) present(alert, animated: true, completion: nil)


Swift 4.0 Ejemplo

Esto se basa en la respuesta de Mihael Isaev. Tuve que cambiarlo un poco para que el botón Guardar NO se active inmediatamente. Intenté con y sin el texto del marcador de posición. Al final, tuve que desactivar específicamente Guardar para comenzar. En mi caso, elegí usar un título de alerta en lugar del texto de marcador de posición. Pero, funcionó igual de cualquier manera.

let alert = UIAlertController(title: "Enter Username", message: nil, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { (action) -> Void in})) let saveAction = UIAlertAction(title:"Save", style: .destructive, handler: { (action) -> Void in }) alert.addAction(saveAction) alert.addTextField(configurationHandler: { (textField) in textField.text = "" saveAction.isEnabled = false NotificationCenter.default.addObserver(forName: NSNotification.Name.UITextFieldTextDidChange, object: textField, queue: OperationQueue.main) { (notification) in saveAction.isEnabled = textField.text!.length > 0 } }) self.present(alert, animated: true, completion: nil)