UITextField does not update caret when toggling isSecureText

Originator:macbellingrath
Number:rdar://38465011 Date Originated:03/14/2018
Status:Open Resolved:
Product:UIKit Product Version:11.2.0
Classification:Bug Reproducible:Always
 
Area:
UIKit

Summary:
If a UITextField contains secure text, toggling `isSecureText` does not update the position of the caret. In our case, this makes it appear as if the field has appended a single white space to the text in the field.

Steps to Reproduce:
- Initialize a UITextField
- Set `isSecureText` to true on the text field
- Enter some text in the field 
- Programmatically toggle `isSecureText` to reveal the masked characters

Expected Results:
When the characters are revealed, there the caret moves to the end of the unmasked characters

Actual Results:
The caret remains in the same position without adjusting for the changed characters. 

Version/Build:
iOS 11.2.0

Configuration:
Xcode 9.2
iPhone X, iOS 11.2.0

Comments

Workaround

Seems update is delayed and rendering is wrong.

In tick, caretRect(for: endOfDocument) becomes correct, but not in immediately after toggling isSecureTextEntry. Rendering must be updated in "not previous value" manner.

Temporary solution before native fix:

    // update caret position
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
        let (beginning, end) = (self.beginningOfDocument, self.endOfDocument)

        self.selectedTextRange = self.textRange(from: beginning, to: end)
        self.selectedTextRange = self.textRange(from: end, to: end)
    }

Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!