Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITextField text jumps

I have ViewController with 2 UITextField elements: Login and Password. I set delegate for these fields, which includes code below:

func textFieldShouldReturn(textField: UITextField) -> Bool {     if textField === self.loginField {         self.loginField.resignFirstResponder()         self.passwordField.becomeFirstResponder()         return false     }      return true } 

This logic should switch user from login text field to password when he presses Next button on keyboard. But I stuck with glitch: after

self.passwordField.becomeFirstResponder() 

text in login field jumps to the top left corner and back. And what's more strange: this glitch reproduces only first time, then you need recreate ViewController to observe this behavior

Here is video of the glitch http://tinypic.com/player.php?v=6nsemw%3E&s=8#.VgVb3cuqpHx

I ended up with this:

func textFieldShouldReturn(textField: UITextField) -> Bool {     if textField === self.loginField {         self.loginField.resignFirstResponder()         // Shitty workaround. Hi, Apple!         self.loginField.setNeedsLayout()         self.loginField.layoutIfNeeded()          self.passwordField.becomeFirstResponder()         return false     }      return true } 
like image 687
user3237732 Avatar asked Sep 24 '15 15:09

user3237732


2 Answers

Based on some of the other ideas posted here, this is a solution that is easy to implement, works (for me) in all cases, and doesn't appear to have any side effects:

- (void)textFieldDidEndEditing:(UITextField *)textField {     // Workaround for the jumping text bug.     [textField resignFirstResponder];     [textField layoutIfNeeded]; } 

This solution works both if you're going to the next field programmatically from -textFieldShouldReturn: or if the user just touches another responder.

like image 168
Dave Batton Avatar answered Oct 04 '22 10:10

Dave Batton


In a UITextField subclass you can do the following:

-(BOOL)resignFirstResponder {     BOOL resigned = [super resignFirstResponder];     [self layoutIfNeeded];     return resigned; } 

The trick here is to make sure you call layoutIfNeeded after resignFirstResponder has been called.

Doing it this way is quite handy because you don't need to call resignFirstResponder in the delegate callbacks yourself as this caused me problems inside a UIScrollView, the above however doesn't :)

like image 23
liamnichols Avatar answered Oct 04 '22 08:10

liamnichols