10

I need the text of the text field to be selected right after the UIAlertController is presented. However, the way I select text in a standard UITextField doesn't work here.

This is what I tried, but I can't seem to get it work.

let ac = UIAlertController(title: "Rename", message: nil, preferredStyle: .Alert)
ac.addTextFieldWithConfigurationHandler({
    [] (textField: UITextField) in
    textField.selectedTextRange = textField.textRangeFromPosition(textField.beginningOfDocument, toPosition: textField.endOfDocument)
    textField.text = "filename.dat"
    })
ac.addAction(UIAlertAction(title: "CANCEL", style: .Cancel, handler: nil))
ac.addAction(UIAlertAction(title: "OK", style: .Default, handler: {
    [] Void in
    // do something
    }))
dispatch_async(dispatch_get_main_queue(), {
    self.presentViewController(ac, animated: true, completion: nil)
})

Any ideas?

Pang
  • 8,605
  • 144
  • 77
  • 113
Antonin Charvat
  • 869
  • 7
  • 16

3 Answers3

14

I have rewrote your code. Your class should conform to the UITextFieldDelegate protocol and implement the textFieldDidBeginEditing method, like this:

class ViewController: UIViewController, UITextFieldDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        let ac = UIAlertController(title: "Rename", message: nil, preferredStyle: .Alert)
        ac.addTextFieldWithConfigurationHandler({
            [] (textField: UITextField) in
            textField.text = "filename.dat"
            textField.delegate = self

        })
        ac.addAction(UIAlertAction(title: "CANCEL", style: .Cancel, handler: nil))
        ac.addAction(UIAlertAction(title: "OK", style: .Default, handler: {
            [] Void in
            // do something
        }))
        dispatch_async(dispatch_get_main_queue(), {
            self.presentViewController(ac, animated: true, completion: nil)
        })

    }
    func textFieldDidBeginEditing(textField: UITextField) {
        textField.selectedTextRange = textField.textRangeFromPosition(textField.beginningOfDocument, toPosition: textField.endOfDocument)
        textField.becomeFirstResponder()
    }

}
Pang
  • 8,605
  • 144
  • 77
  • 113
ridvankucuk
  • 2,338
  • 1
  • 20
  • 38
8

A way to select all text without adding a delegate:

present(vc, animated: true) {
    vc.textFields?.first?.selectAll(nil)
}
pkamb
  • 26,648
  • 20
  • 124
  • 157
zgjie
  • 1,969
  • 1
  • 19
  • 26
7

Thanks, @ridvankucuk. Your solution works great.

But textfield delegate function can be simplified little bit:

func textFieldDidBeginEditing(_ textField: UITextField) {
    textField.selectAll(nil)
}
seelts
  • 1,086
  • 14
  • 32
  • I notice you omitted `textField.becomeFirstResponder()` from @ridvankucuk's answer. Are there situations where that line should be added back in? – ToolmakerSteve Mar 14 '17 at 05:00
  • 2
    @ToolmakerSteve, personally, I have never met with such situations. Text field is already first responder when `textFieldDidBeginEditing:` method is called. But may be you have some special case, when you need to make it first responder again. – seelts Mar 14 '17 at 09:46