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)
}
これは、Eメールフィールドを検証するための関数です。
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
}
これは、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)
}
最もエレガントな方法は使用することです
NotificationCenter.default.addObserver(forName: 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: NSNotification.Name.UITextFieldTextDidChange, object: textField, queue: OperationQueue.main) { (notification) in
saveAction.isEnabled = textField.text!.length > 0
}
})
present(alert, animated: true, completion: nil)
Swift 4.0の例
これはミハエル・イサエフの答えに基づいています。 [保存]ボタンがすぐにアクティブにならないようにするには、少し変更する必要がありました。プレースホルダーテキストありとなしで試してみました。結局、最初に保存を明確に非アクティブ化する必要がありました。私の場合、プレースホルダーテキストではなくアラートタイトルを使用することにしました。しかし、どちらの方法でも同じように機能しました。
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)
以下のコードを使用して、UIAlertControllerのTextFieldを検証できます。
ステップ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._%+-]+@[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];
これは、アラートコントローラーを表示する前に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._%+-]+@[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
}
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)
テキストフィールドの変更通知に登録し、そこでテキストフィールドを検証します。
//...
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)
//...
私は a 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)
}
}
}
したがって、あなたのケースでは、追加する必要がある唯一の追加事項は、textChangeActionハンドラーでisValidEmail関数を呼び出すことです。
alert.addTextField(configurationHandler: { (textField) in
// things you want to configure on the textfield
}) { (textField) in
saveAction.isEnabled = isValidEmail(textField.text ?? "")
}
@KupendiranがUIAlertControllerによる電子メール入力検証のために提示したものに続いて。 Objective-Cで動作するバージョンと、UIAlertViewが廃止された新しいUIAlertController形式を以下に示します。
手順1.以下を.hおよび.mファイルに追加し、他のプロパティと変数を追加する
.h
@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._%+-]+@[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];