How do I validate TextFields in an UIAlertController?

后端 未结 10 2277
不思量自难忘°
不思量自难忘° 2020-12-14 08:54

Can anyone tell me how to validate UITextFields inside of a UIAlertController?

I need it to prevent the user from clicking \"Save\" unless

相关标签:
10条回答
  • 2020-12-14 09:00

    Register for the text field change notifications and validate the text fields there:

    //...
    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)
    //...
    
    0 讨论(0)
  • 2020-12-14 09:01

    Following what @Kupendiran presented for email input validation with UIAlertController. Here is a version thats working with Objective-C and the newer UIAlertController format as UIAlertView is now depreciated.

    Step 1. add the following to .h and .m files with other properties and variables

    .h

    @property(strong,nonatomic)UITextField *emailAddressField;
    

    .m

    UITextField *emailAddressField;
    

    Step 2. Create the alert message, buttons and validation process.

    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;
            }];
    

    Step 3. Create the alert actions

            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 (example@example.com 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];
    

    Step 4. Present the alert message on the screen

    [self presentViewController:alertView animated:YES completion:nil];
    
    0 讨论(0)
  • 2020-12-14 09:02

    This can be done by extending 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)
    }
    

    0 讨论(0)
  • 2020-12-14 09:02

    Most elegant way is to use

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

    Swift 3.0 example

    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)
    
    0 讨论(0)
  • 2020-12-14 09:02

    For Swift 4.2 (NSNotification.Name.UITextFieldTextDidChange) update:

    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)
    
    0 讨论(0)
  • 2020-12-14 09:04

    Swift 4.0 Example

    This is based on Mihael Isaev's answer. I had to change it up a bit to get the Save button to NOT be active immediately. I tried with and without the placeholder text. In the end, had to specifically inactivate Save to start with. In my case, I elected to use an alert title rather than placeholder text. But, it worked the same either way.

    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)
    
    0 讨论(0)
提交回复
热议问题