Клавиатура не исчезает после viewDidDisappear

iOS 11.2, Xcode 9.2

Я пробовал все способы отключить клавиатуру на viewDidDisappear старого UIViewController ПОСЛЕ новый UIViewController помещается в стек UINavigationController. Но без везения.

Если я закрою его viewWillDisappear - он закроется, но с анимацией ВО ВРЕМЯ пуш-анимации. Это нежелательное поведение. Я хочу, чтобы старая клавиатура UIViewController закрывалась только тогда, когда контроллер больше не виден.

Поведение должно быть как в приложении Telegram:

В любом диалоге с видимой клавиатурой нажмите на аватар оппонента, и вы перейдете к информации об аккаунте оппонента. Затем, если вы нажмете кнопку «Назад», вы будете перенаправлены обратно в диалоговое окно. Но клавиатура будет уже уволена.

Любая помощь приветствуется!

P.S. Вопрос может выглядеть как дубликат, но мне не удалось заставить его работать с найденными решениями.

Изменить 1.

Я создал небольшой ТЕСТ-ПРОЕКТ, который представляет собой неспособность достичь желаемого поведение.

Чтобы воспроизвести нежелательное поведение:

  • Запустите приложение.
  • Нажмите на UITextField или UITextView и дождитесь появления клавиатуры.
  • Нажмите кнопку «Далее» и дождитесь нажатия нового контроллера.
  • Нажмите кнопку «Назад» и дождитесь появления нового контроллера.

В результате начальный контроллер представления будет иметь активную клавиатуру после действий push/pop. Мне нужно, чтобы клавиатура была скрыта после действий push/pop. Кроме того, клавиатуру не следует убирать до того, как начальный контроллер представления станет невидимым, ее следует убирать после действия viewDidDisappear.


person iWheelBuy    schedule 16.12.2017    source источник


Ответы (2)


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

Используйте свойство: isEditable вашего textView. Вот проверенный код:

  override func viewWillAppear(_ animated: Bool) {
    self.viewTextView.isEditable = false
    super.viewWillAppear(animated)
  }

  override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    self.viewTextView.isEditable = true
  }

Результаты:

введите здесь описание изображения

Комментарии от @iWheelBuy:

Иногда текстовые представления будут иметь inputAccessoryView. То, как вы это сделаете, приведет к исчезновению клавиатуры, но inputAccessoryView останется... Вот почему вы также должны сделать inputAccessoryView = nil или inputAccessoryView = UIView() при установке isEditable = false

person Neil Galiaskarov    schedule 18.12.2017
comment
Действительно, я скачал ваш проект и он не работает. Пожалуйста, проверьте мой обновленный ответ, который работает с вашим проектом. - person Neil Galiaskarov; 19.12.2017
comment
Есть одна маленькая вещь, которую также следует упомянуть в вашем ответе. Иногда текстовые представления будут иметь inputAccessoryView. То, как вы это сделаете, приведет к исчезновению клавиатуры, но inputAccessoryView останется... Вот почему вы также должны сделать inputAccessoryView = nil или inputAccessoryView = UIView() при установке isEditable = false - person iWheelBuy; 19.12.2017

Проблема возникает из-за того, что респонденты управляются (восстанавливаются, сохраняются) UIKit между viewWillAppear и viewDidAppear непосредственно перед появлением представления и между viewWillDisapear: и viewDidDisapear: непосредственно перед исчезновением представления. Вот почему любые изменения, внесенные в респондеры, видны во время анимации.

Вместо удаления респондентов, чтобы получить желаемый эффект, вы можете запретить представлениям становиться респондентами до того, как представление появится снова.

Самый простой способ сделать это для UITextField и UITextView — временно отключить взаимодействие непосредственно перед появлением представления, а затем восстановить его после того, как представление снова появится.

override func viewWillAppear(_ animated: Bool) {
    self.viewTextField.isUserInteractionEnabled = false
    self.viewTextView.isUserInteractionEnabled = false
    super.viewWillAppear(animated)
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    self.viewTextField.isUserInteractionEnabled = true
    self.viewTextView.isUserInteractionEnabled = true
}

Это даст вам тот же эффект, что и Telegram.

person XeNoN    schedule 18.12.2017
comment
Этот трюк работает с UITextField, но не работает с UITextView... И в моем проекте есть только UITextViews...): - person iWheelBuy; 19.12.2017