7

I have added a UITextField to UIAlertController, but shouldChangeCharactersInRange will get not fired. Why? I set the delegate.

let alertController = UIAlertController(title: "", message: "xxx", preferredStyle: .Alert) self.presentViewController(alertController, animated:true, completion:nil) let textField = UITextField() textField.delegate = self alertController.addTextFieldWithConfigurationHandler(nil) 

and in the same class, the delegate:

func textField(textField: UITextField!, shouldChangeCharactersInRange range: NSRange, replacementString string: String!) -> Bool { 

2 Answers 2

14

The text field that you're setting the delegate for is not the same text field that is added to the alert controller. Basically, you're creating a new instance of UITextField, but never giving it a frame, or adding it to the view hierarchy. At the same time, you're using addTextFieldWithConfigurationHandler() to add a text field to the alert controller, but you never set the delegate for this text field. I believe this is what you want:

let alertController = UIAlertController(title: "", message: "xxx", preferredStyle: .Alert) alertController.addTextFieldWithConfigurationHandler {[weak self] (textField: UITextField!) in textField.delegate = self } self.presentViewController(alertController, animated:true, completion:nil) 
Sign up to request clarification or add additional context in comments.

Comments

2

I was unable to get this working with UITextFieldDelegate. The delegate was set correctly but not being called for the UITextField within a UIAlertController.

Based on the answer here How do I validate TextFields in an UIAlertController? I learned you can instead use addTarget for UIControl.Event.editingChanged to call a selector when the editing changes.

let alertController = UIAlertController(title: "Title", message: "message", preferredStyle: .alert) alertController.addTextField { (textField : UITextField!) -> Void in /* * Alternative to UITextFieldDelegate */ textField.addTarget(alertController, action: #selector(alertController.textDidChange), for: .editingChanged) } let searchAction = UIAlertAction(title: "Search", style: .default) let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil ) alertController.addAction(searchAction) alertController.addAction(cancelAction) present(searchAlertController, animated: true) 

You can extend or subclass UIAlertController to add the selector:

extension UIAlertController { @objc func textDidChange() { guard let textField = textFields?.first else { return } guard let searchAction = actions.first(where: { $0.title == "Search" }) else { return } let text = textField.text?.trimmingCharacters(in: .whitespacesAndNewlines) ?? "" searchAction.isEnabled = !text.isEmpty } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.