Как проверить текстовые поля в UIAlertController?
Может ли кто-нибудь сказать мне, как проверить UITextFields
внутри UIAlertController
?
Мне нужно, чтобы пользователь не нажал "Сохранить", если оба поля не введены.
Вот мой код:
@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)
}
Это моя функция для проверки поля электронной почты:
func isValidEmail(testStr:String) -> Bool {
let emailRegEx = "[A-Z0-9a-z._%+-][email protected][A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"
if let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx) {
return emailTest.evaluateWithObject(testStr)
}
return false
}
Ответы
Ответ 1
Самый элегантный способ - использовать
NotificationCenter.default.addObserver(forName: NSNotification.Name.UITextFieldTextDidChange...
Пример 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)
Ответ 2
Это можно сделать, расширив UIAlertViewController
:
extension UIAlertController {
func isValidEmail(_ email: String) -> Bool {
return email.characters.count > 0 && NSPredicate(format: "self matches %@", "[a-zA-Z0-9._%+-][email protected][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)
}
Ответ 3
Это может быть достигнуто с помощью NSNotificationCenter перед отображением контроллера предупреждений, все, что вам нужно сделать, это попросить центр уведомлений наблюдать за уведомлением для UITextFieldTextDidChangeNotification, и вы должны быть хорошими,
Ниже приводится реализация для того же
@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._%+-][email protected][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
}
Ответ 4
Вы можете использовать нижеприведенный код для проверки TextFields в UIAlertController: -
Шаг 1:
Declare "email_TF" to your viewcontroller.h
for example:
@property(strong,nonatomic)UITextField *email_TF;
Шаг 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;
}];
Шаг 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._%+-][email protected][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];
Шаг 4:
[self presentViewController:alert animated:YES completion:nil];
Ответ 5
Пример Swift 4.0
Это основано на ответе Михаила Исаева. Мне пришлось немного изменить его, чтобы кнопка "Сохранить" НЕ была активной. Я пробовал с текстом заполнителя и без него. В конце концов, для того, чтобы начать, нужно было специально инактивировать Save. В моем случае я решил использовать заголовок предупреждения, а не текст заполнителя. Но это сработало одинаково.
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)
Ответ 6
Зарегистрируйтесь для уведомлений об изменении текстового поля и подтвердите наличие текстовых полей:
//...
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)
//...
Ответ 7
Я реализовал подкласс UIAlertController, который позволяет добавлять обработчик в текстовые поля при добавлении его в предупреждение:
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)
}
}
}
Поэтому для вашего случая единственной дополнительной возможностью, которую нужно добавить, является вызов функции isValidEmail в обработчике textChangeAction:
alert.addTextField(configurationHandler: { (textField) in
// things you want to configure on the textfield
}) { (textField) in
saveAction.isEnabled = isValidEmail(textField.text ?? "")
}
Ответ 8
Во-первых, вам нужно добавить некоторые переменные в ваш класс:
private weak var saveAction : UIAlertAction?
private weak var textFieldName : UITextField?
private weak var textFieldEmail : UITextField?
private var validName = false
private var validEmail = false
Затем, когда вы хотите настроить контроллер предупреждений (я только вставил вещи, которые нужно изменить):
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
Наконец, вы должны реализовать этот метод делегата:
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
}
Ответ 9
После того, что @Kupendiran представил для проверки ввода электронной почты с помощью UIAlertController. Вот версия, которая работает с Objective-C и более новым форматом UIAlertController, поскольку UIAlertView теперь обесценивается.
Шаг 1. добавьте следующие файлы.h и.m с другими свойствами и переменными
.час
@property(strong,nonatomic)UITextField *emailAddressField;
.m
UITextField *emailAddressField;
Шаг 2. Создайте предупреждающее сообщение, кнопки и процесс проверки.
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;
}];
Шаг 3. Создайте действия оповещения
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._%+-][email protected][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];
Шаг 4. Представьте предупреждающее сообщение на экране
[self presentViewController:alertView animated:YES completion:nil];