iosswiftuiviewcontrollerresignfirstresponder

Keyboard doesn't go away with resignFirstResponder


I have a view controller that requires the user to select several things. Using UIPickerView directly wont' work because they take up too much room. So instead I have several UITextField, when a user selects one, it brings up a modal view controller. It works fine so far, except when there is already a keyboard visible. When this happens the modal view controller is presented, but it is covered up by the previous keyboard. This keyboard does not appear to be attached to any UITextField, in the sense that pressing keys on it does not result in characters appear in any UITextField. Though a blinking cursor does appear in the text field.

protocol ModalPickerTarget {
    var cancelCallback: (() -> Void)? { set get }
    var selectCallback: ((String) -> Void)? { set get }
}

class ModalPicker<T> where T: UIViewController, T: ModalPickerTarget {
    weak var controller: UIViewController!
    weak var textField: UITextField!

    init(textField: UITextField, controller: UIViewController) {
        self.controller = controller
        self.textField = textField
        textField.addTarget(self, action: #selector(ModalPicker.show), for: .editingDidBegin)
    }

    @objc func show(sender: AnyObject) {
        var modal = T()

        print("First responder: \(self.textField.isFirstResponder)")
        self.textField.resignFirstResponder()
        modal.modalPresentationStyle = .overCurrentContext
        modal.modalTransitionStyle = .crossDissolve

        modal.cancelCallback = {
            modal.dismiss(animated: true, completion: nil)
        }

        modal.selectCallback = {
            modal.dismiss(animated: true, completion: nil)
            self.textField.text = $0
        }

        self.controller.present(modal, animated: true, completion: nil)
    }
}

The print statement indicates that textField is the first responder. I've also tried calling endEditing on the parent and modal views with no effect.

Here are some screen shots

Modal presented properly Keyboard not hiding


Solution

  • You have to return false on textFieldShouldBeginEditing

    func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
        // Implement your Picker there
      return false
    }