Подтвердить что ты не робот

Переходы текста UITextField

У меня есть ViewController с 2 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
}
4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

Трюк здесь состоит в том, чтобы вы вызывали layoutIfNeeded после того, как был вызван resignFirstResponder.

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

Ответ 3

Используйте этот код, чтобы избежать перескакивания текста в 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()
}

Ответ 5

func textFieldDidEndEditing(_ textField: UITextField) {

    textField.layoutIfNeeded()
}

Ответ 6

Основываясь на том, что я понимаю из этого:

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

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

Ответ 7

Я не передаю делегатам текстовых полей. Вместо этого я создаю 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().

Ответ 8

Более "общий" вариант заключается в том, чтобы использовать уведомления прямо внутри вашего подкласса UITextField:

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

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

Не забывайте отписаться