iosswiftuitextfieldinputview

'UIViewControllerHierarchyInconsistency' thrown when using a UIViewController's view as UITextField's inputView


I spent the day trying to figure out a crash on my app related with a textfield's inputView. I've tried making a test project to reproduce the crash. Here's what I have :

class ViewController: UIViewController {

  let keyboardVC = KeyboardViewController()

  override func viewDidLoad() {
    super.viewDidLoad()

    keyboardVC.view.backgroundColor = .blue

    let textField = UITextField()
    textField.inputView = keyboardVC.view
    textField.backgroundColor = .red

    view.addSubview(textField)
  }
}

If I tap once on the textfield, everything works as expected, my blue view is displayed instead of the keyboard. But if I tap multiple times on the textField during the inputView animation, the app crashes with the following exception:

*** Terminating app due to uncaught exception 
'UIViewControllerHierarchyInconsistency', reason: 'child view 
controller:<Test.KeyboardViewController: 0x7ff53c008f20> should have 
parent view controller:<UICompatibilityInputViewController: 
0x7ff539403a40> but requested parent is:<UICompatibilityInputViewController: 0x7ff53940e330>'

I am probably missing something obvious but I can't figure out what's is going on... Any help is appreciated :)

Thanks!


Solution

  • The problem lies in the fact that you are trying to add a view of another view controller to the view controller with the textfield.

    Try the following:

    let inputView = UIView(frame: CGRect(x:0,y:0,width:keyboardVC.view.frame.width, height: keyboardVC.view.frame.height))
    inputView.addSubview(keyboardVC.view)
    addChildViewController(keyboardVC)
    keyboardVC.didMove(toParentViewController: self)
    textField.inputView = inputView