2015-09-24 3 views
46

У меня есть ViewController с 2 UITextField элементов: Логин и Пароль. Я поставил делегат для этих полей, который включает в себя код ниже:UITextField текст прыгает

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

    return true 
} 

Эта логика должна переключить пользователя из текстового поля для входа в пароль, когда он нажимает кнопку Далее на клавиатуре. Но я застрял с ошибкой: после

self.passwordField.becomeFirstResponder() 

Текст в поле ввода перескакивает в верхний левый угол и обратно. И что более странно: этот глюк воспроизводит только первый раз, то вам необходимо заново ViewController наблюдать такое поведение

Вот видео глюк http://tinypic.com/player.php?v=6nsemw%3E&s=8#.VgVb3cuqpHx

я закончил с этим:

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 
} 
+0

Что вы подразумеваете под текстом в поле входа, прыгает в верхний левый угол? Можем ли мы увидеть скриншот? – chrisamanse

+0

http://i.piccy.info/i9/a1de3ab9cb8fa4ee64d50d250d4d69f5/1443110450/73928/953432/Simulator_Screen_Shot.jpg Текст переходит к левому верхнему углу текстового поля, а затем падает обратно – user3237732

+0

Возможно, у вас есть проблемы со строковыми атрибутами. – kelin

ответ

0

I не предоставляйте делегатам текстовых полей. Вместо этого я создаю IBAction и присоединяю его к событию «Закончено на выход». Сбой также случается с этим методом, но только в iOS 9. Он выглядит как ошибка ОС.

Мои действия выглядит следующим образом:

@IBAction func textFieldAction(sender: UITextField) { 
    if sender === usernameField { 
     passwordField.becomeFirstResponder() 
    } 
} 

С выше, глюк происходит, но когда я ниже глюк уходит:

@IBAction func textFieldAction(sender: UITextField) { 
    if sender === usernameField { 
     sender.resignFirstResponder() 
     passwordField.becomeFirstResponder() 
    } 
} 

Я, кажется, не нужно для звонка setNeedsLayout().

0

Больше «родовое» вариант заключается в использовании уведомлений прямо внутри UITextField подкласса:

- (void)setupJumpingTextWorkaround { 
    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(forceLayout) 
               name:UITextFieldTextDidEndEditingNotification object:self]; 
} 

- (void)forceLayout { 
     [self setNeedsLayout]; 
     [self layoutIfNeeded]; 
    } 

Не забудьте отписаться

48

Основываясь на некоторых других идей, размещенных здесь, это которое во многих случаях работает (для меня) и не имеет побочных эффектов:

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

Это решение работает и в том случае, если вы программно выбираете следующее поле от -textFieldShouldReturn: или если пользователь просто касается другого ответчика.

+2

Это действительно удивительный и самый простой ответ :) –

+0

Это работает, если текст виден. Однако, если текст имеет secureTextEntry установлен на YES, это не устраняет проблему. – jungledev

+0

Наконец-то! Совершенное исправление +1 – aboodmufti

15

В UITextField подкласса вы можете сделать следующее:

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

Хитрость здесь, чтобы убедиться, что вы звоните layoutIfNeededпослеresignFirstResponder был вызван.

делая это таким образом очень удобно, потому что вам не нужно вызывать resignFirstResponder в делегатом обратные вызовы себя, так как это вызвало у меня проблемы внутри UIScrollView, выше, однако, не :)

+0

Thx, это решение для меня! –

+0

Очень элегантный и, самое главное, он работает! –

+0

@iamnichols спас меня. –

8

Используйте этот код избегайте перескакивания текста в UITextField.

- (BOOL) textFieldShouldReturn:(UITextField *)textField{ 

     if(textField == self.txtUserName){ 
     [self.txtEmail becomeFirstResponder]; 
     } 
     else if (textField == self.txtEmail){ 
     [self.txtPassword becomeFirstResponder]; 
     } 
     else if (textField == self.txtPassword){ 
     [self.txtConfirmPassword becomeFirstResponder]; 
     } 
     else if (textField == self.txtConfirmPassword){ 
     [self.txtFirstName becomeFirstResponder]; 
     } 
     else{ 
     [textField resignFirstResponder]; 
     } 

    return YES; 
} 

- (void)textFieldDidEndEditing:(UITextField *)textField 
{ 
    [textField resignFirstResponder]; 
    [textField layoutIfNeeded]; 
} 
4
func textFieldDidEndEditing(_ textField: UITextField) { 

    textField.layoutIfNeeded() 
} 
+0

Хотя этот код может ответить на вопрос, предоставление дополнительного контекста относительно того, как и/или почему оно решает проблему, улучшит долгосрочную ценность ответа. –

5

Я также сталкиваются с той же проблемой. Следующий код работает для меня.

func textFieldDidEndEditing(_ textField: UITextField) { 

    textField.layoutIfNeeded() 
} 
1

Основываясь на том, что я понял из this:

Эта проблема может возникнуть, когда у вас есть изменения макета или анимация, обрабатываемая в функции обратного вызова для клавиатуры будет показывать и скрывать уведомления (как правило, в тех случаях, когда вы хотите текстовое поле будет нажато, чтобы клавиатура не скрывала его).

Решение: Я столкнулся с этой проблемой, поскольку я выполнял layoutIfNeeded каждый раз, когда клавиатура будет отображаться, получив вызов, предполагая ее безопасную, очевидно, ее нет, поэтому, когда я делаю чек, чтобы сделать это, только когда есть необходимость в изменении кадров, прыжок остановился.

Смежные вопросы