patrickS
patrickS

Reputation: 3760

Setting the cursor to the end of a UITextField on become first responder

I have a UITextField with a text alignment set to right embedded in a UICollectionViewCell. If I tap the UITextField the cursor should be at the end of the text. Also if I tap the textfield on or before of the beginning of the text. I tried to set the position in the textFieldDidBeginEditing delegate method:

func textFieldDidBeginEditing(_ textField: UITextField) {
    let position = textField.endOfDocument
    textField.selectedTextRange = textField.textRange(from: position, to: position)
}

But this didn't work so I tried it with DispatchQueue.main.async. That works. But I know, that this isn't the most elegant way and it looks like something tries to set the cursor position at the same time.

func textFieldDidBeginEditing(_ textField: UITextField) {
    DispatchQueue.main.async {
        let position = textField.endOfDocument
        textField.selectedTextRange = textField.textRange(from: position, to: position)
    }
}

Is there a better solution to set the cursor on the last position?

Upvotes: 1

Views: 2202

Answers (1)

Ernie Thomason
Ernie Thomason

Reputation: 1709

Using DispatchQueue makes my cursor visually jump, since there's a delay. I'm not sure the solution below is better since it adds complexity, but I'm trying it out.

func textFieldDidBeginEditing(_ textField: UITextField) {
    _beganEditing = true    // if we change cursor position here (with DispatchQueue), cursor jumps ; instead, do in DidChangeSelection
}

func textFieldDidChangeSelection(_ textField: UITextField) {
    // We assume this is called right after DidBeginEditing
    // Move cursor to end if approp
    if (_beganEditing) {
        _beganEditing = false
        if (_rightAlign) {
            let position = textField.endOfDocument
            textField.selectedTextRange = textField.textRange(from: position, to: position)
        }
    }
}

Upvotes: 1

Related Questions