关于ios:viewDidDisappear后键盘不会消失

Keyboard does not disappear after viewDidDisappear

iOS 11.2,Xcode 9.2

在新的UIViewController被推入UINavigationController堆栈之后,我已经尝试了所有方法来解除旧UIViewControllerviewDidDisappear上的键盘。但没有运气。

如果我在viewWillDisappear上解雇它 - 它将被解雇,但在动画播放期间使用动画。这不是理想的行为。我希望只有当控制器不再可见时才能解除旧的UIViewController键盘。

行为应该像电报应用程序:

在任何带有可见键盘的对话框中按下对手头像,您将被推送到对手的账户信息。然后,如果按后退按钮,您将被重定向回对话框。但是键盘已经被解雇了。

任何帮助表示赞赏!

附:问题可能看起来像是重复的,但我没有使用我找到的解决方案。

编辑1。

我创建了一个小的TEST PROJECT,表示无法实现所需的行为。

为了重现不良行为:

  • 启动应用程序。
  • 点击UITextFieldUITextView,然后等待键盘出现。
  • 点击"下一步"按钮,等待推送新控制器。
  • 点击"返回"按钮,等待弹出一个新的控制器。

因此 - 初始视图控制器将在推/弹动作之后具有活动键盘。我需要在推/弹动作后隐藏键盘。此外,在初始视图控制器变为不可见之前不应关闭键盘,在viewDidDisappear动作之后应该将其解除。


出现问题是因为响应者在视图出现之前在viewWillAppearviewDidAppear之间由UIKit管理(恢复,保存),在视图消失之前在viewWillDisapear:viewDidDisapear:之间进行管理(恢复,保存)。这就是为什么在动画期间对响应者所做的任何更改都是可见的。

您可以在视图再次显示之前阻止视图成为响应者,而不是删除响应者,以获得所需的效果。

UITextFieldUITextView执行此操作的最简单方法是在视图出现之前临时禁用交互,然后在视图重新出现后恢复它。

1
2
3
4
5
6
7
8
9
10
11
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相同的效果。


在某些情况下,没有文本字段是第一响应者,但键盘在屏幕上。在这些情况下,上述方法无法解除键盘。

使用textView的属性:isEditable。这是一个经过测试的代码:

1
2
3
4
5
6
7
8
9
  override func viewWillAppear(_ animated: Bool) {
    self.viewTextView.isEditable = false
    super.viewWillAppear(animated)
  }

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

结果:

enter image description here

来自@iWheelBuy的评论:

Sometimes, text views will have inputAccessoryView. The way you do it
will make the keyboard disappear, but the inputAccessoryView will
remain... That is why you should also make inputAccessoryView = nil
or inputAccessoryView = UIView() when setting isEditable = false