UINavigationController后退按钮没有结束UITextField编辑

问题描述 投票:0回答:1

如果导航控制器维护对其子级的引用,则[[按UINavigationController向后按钮]不会永久结束对子视图控制器上UITextField的编辑。将子视图控制器推回堆栈会立即导致文本字段恢复编辑,从而使键盘弹出。您必须手动呼叫popViewController()

复制步骤(为简化起见,以XCode操场风格呈现)

  1. 用单个文本字段定义视图控制器,并在视图消失时通知文本字段结束编辑
class TextFieldViewController: UIViewController {

    let textField = UITextField()

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        self.textField.endEditing(true)
    }
}
  1. 定义一个导航控制器,该控制器维护对视图控制器的2个实例的引用。
class MyNavigationController: UINavigationController {
    let textFieldVC1 = TextFieldViewController()
    let textFieldVC2 = TextFieldViewController()
}
  1. 创建导航控制器,并将第一个子VC设置为root。
let myNavVC = MyNavigationController()
myNavVC.setViewControllers([myNavVC.textFieldVC1], animated: false)
  1. 推送第二个VC
myNavVC.pushViewController(myNavVC.textFieldVC2, animated: true)
  1. 点击第二个VC中的文本字段以调出键盘

  2. 按下导航控制器的后退按钮:endEditing(_:)被调用,并且键盘被关闭

  3. 将第二个VC推回到堆栈中

myNavVC.pushViewController(myNavVC.textFieldVC2, animated: true)

结果:键盘再次弹出,并且文本字段调用textFieldDidBeginEditing(_:)

我已经尝试将对endEditing(_:)的调用移到各种视图控制器生命周期方法中(即willMove(toParent:)didMove(toParent:)等)无效。我也尝试过将其他呼叫添加到resignFirstResponder()


完整代码:

class ViewController: UIViewController {

    var navVC: UINavigationController!
    let textFieldVC1 = TextFieldViewController()
    let textFieldVC2 = TextFieldViewController()

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        self.navVC = segue.destination as? UINavigationController
        navVC!.setViewControllers([self.textFieldVC1], animated: false)
    }
}

class TextFieldViewController: UIViewController, UITextFieldDelegate {

    let textField = UITextField()

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.addSubview(self.textField)
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        self.textField.frame = CGRect(x: 16, y: 64, width: 200, height: 48)
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        self.view.endEditing(true)
    }

}

故事板:

Storyboard File

swift uinavigationcontroller uitextfield
1个回答
1
投票

问题是这里的技巧:

class MyNavigationController: UINavigationController {
    let textFieldVC1 = TextFieldViewController()
    let textFieldVC2 = TextFieldViewController()
}

您现在保留了对两个视图控制器的引用,因此它们都不存在。这不是导航控制器应该工作的方式。您已经破坏了整个视图控制器架构。当我们从视图控制器弹出时,它应该go of exist,这将解决您遇到的问题。但是您的子视图控制器可能never不存在,因为您将其保留在此处。

如果导航控制器保留对其子级的引用

哦,所以您已经知道,这就是问题所在!优秀。所以解决方案很简单:不要那样做。这是错误的,正如您所看到的,它使您不知所措。

((我不知道为什么,或者为什么您认为适合UINavigationController的子类,这几乎总是一个坏主意。也许您正在尝试解决一些更有趣的问题;也许您应该询问这个问题。)

© www.soinside.com 2019 - 2024. All rights reserved.