我在导航控制器中有 2 个控制器。第一个将第二个推送到堆栈,用户可以与那里的文本字段进行交互。然后(在一种情况下)用户将点击后退按钮以转到上一个屏幕。假设第二个加载是"重的",所以一旦需要,我将只保留它的一个实例。
预期:我想在按下后退按钮后隐藏键盘。
实际:当我第二次回到第二个响应者时,第一个响应者不断恢复。如何预防?辞职的第一响应者也不起作用......
问题演示:https://gitlab.com/matrejek/TestApp
主要代码部分:
class FirstViewController: UIViewController {
var child: UIViewController = {
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let vc = storyboard.instantiateViewController(withIdentifier: "child")
return vc
}()
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func onButtonTap(_ sender: Any) {
self.navigationController?.pushViewController(child, animated: true)
}
}
class SecondViewController: UIViewController {
@IBOutlet weak var textField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
view.endEditing(true)
}
}
这看起来确实很奇怪---,似乎你的方法应该有效。
显然(基于快速测试),由于您不允许导航控制器释放 SecondVC,因此文本字段保持"活动"状态。
如果您将其添加到SecondViewController
,它将阻止键盘在您下次导航到控制器时"自动重新显示" - 不确定它是否适合您,但它可以完成这项工作:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
DispatchQueue.main.async {
self.view.endEditing(true)
}
}
编辑:Jan 25 2020
根据新的评论,是的,这似乎是一个错误。
我以前的变通方法答案奏效了——有点。结果是键盘弹出,然后在随后的child
推动中消失。
以下是更好的解决方法。我们必须SecondViewController
符合UITextFieldDelegate
并添加一个 BOOL 类 var/属性,以防止文本字段成为第一响应者。注释应明确:
class FirstViewController: UIViewController {
var child: UIViewController = {
let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
let vc = storyboard.instantiateViewController(withIdentifier: "child")
return vc
}()
@IBAction func onButtonTap(_ sender: Any) {
self.navigationController?.pushViewController(child, animated: true)
}
}
// conform to UITextFieldDelegate
class SecondViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var textField: UITextField!
// bool var to prevent text field re-becoming first responder
// when VC is pushed a second time
var bResist: Bool = false
override func viewDidLoad() {
super.viewDidLoad()
// assign text field delegate
textField.delegate = self
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// view has appeared, so allow text field to become first responder
bResist = false
}
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
return !bResist
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// end editing on this view
view.endEditing(true)
// we want to resist becoming first responder on next push
bResist = true
}
}