Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITextField has trailing whitespace after secureTextEntry toggle

I have a button that toggles between Show/Hide mode (i.e. toggles a UITextField between secureTextEntry NO and YES). The purpose of which is to allow the user to see the password they are entering.

I followed the example (with the highest number of votes) here: UITextField secureTextEntry - works going from YES to NO, but changing back to YES has no effect

However, when I set secureTextEntry to NO, any text that was written there ends up with a space at the end. This does not seem to be a problem when setting secureTextEntry to YES.

For example, if I enter the text "mypassword" while setSecureTextEntry is set to NO, and then switch it to YES, the user will see ********** (10 dots), which is correct. If I setSecureTextEntry to NO, the user will see "mypassword " (with a space at the end, or at least, the cursor moved one space to the right).

Important note: In the debugger, the string value of text appears without the trailing space, like this:

(lldb) expr self.passwordText.text (NSString *) $0 = 0x1d8450e0 @"mypassword" 

I have tried trimming whitespace (per avoid middle whitespace in UITextField), but it has had no effect.

like image 862
Brian Colavito Avatar asked Jan 08 '13 16:01

Brian Colavito


2 Answers

i've just encounter this case and finally solved this problem.

works on Latest iOS SDK, iOS 8.1

First of all, there is no trailing space at all.

The dot(shown in SecureEntry) character and normal character have different width and after you toggle isSecureEntry switch, the cursor didn't refresh it's position.

so i use this workaround to solved this problem.

- (void)toggle {     NSString *tmpString;     [self.passwordTextField setSecureTextEntry:!self.passwordTextField.isSecureTextEntry];     if (self.passwordTextField.isSecureTextEntry) {        // do stuffs     } else {        // do other stuffs     }     // Workaround to refresh cursor     tmpString = self.passwordTextField.text;     self.passwordTextField.text = @" ";     self.passwordTextField.text = tmpString; } 

Swift 3+

   // Workaround to refresh cursor      let currentText: String = self.userPassword.text!     self.userPassword.text = "";     self.userPassword.text = currentText 

hope it helps!

like image 160
sunus Avatar answered Sep 20 '22 22:09

sunus


PRE-iOS-8.0 (dated solution)... In your button's action method (toggling between secureTextEntry YES and NO), simply set UITextField's text property to its current text value. Although this may seem redundant and a bit like a hack, this will redraw the cursor in the right position. Here's an example of what your button's action method should look like now...

-(void)toggleButtonPressed:(UIButton*)sender {     // Toggle between secure and not-so-secure entry     self.toggleButton.selected = !self.toggleButton.selected;     self.textfield.secureTextEntry = !self.toggleButton.selected;      // * Redundant (but necessary) line *     [self.textfield setText:self.textfield.text]; } 

POST-iOS-8.0... As of iOS 8.0, it appears that UITextField's text setter no longer redraws the cursor when called with a string equal to its current string value. Now, we need to take this a step further and actually change the text value before resetting it again. Replace the above setText: line with something like these lines.

// * Extra redundant (but necessary) lines * NSString *currentText = self.textfield.text; [self.textfield setText:@"Arbitrary string..."]; // Change the value [self.textfield setText:currentText]; // Reset the value 
like image 38
Matthew Avatar answered Sep 19 '22 22:09

Matthew