I’m building a custom iOS keyboard using UIInputViewController. I want to toggle between my custom keyboard (with a custom view and accessory view) and the system keyboard (default QWERTY). However, when I try to reset inputView to show the system keyboard, I get a blank view instead.
Here’s what I’m doing in my showEnglishKeyboard function:
swift
private func showEnglishKeyboard() {
// Hide custom panels
suggestionPanel.isHidden = true
accessoryView.isHidden = false
// Reset to system keyboard
self.resignFirstResponder() // Dismiss current keyboard
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.inputView = nil // Reset inputView to default keyboard
self.reloadInputViews() // Reload keyboard
self.becomeFirstResponder() // Reactivate input controller
}
}
I’ve also overridden viewWillLayoutSubviews to ensure the height of the custom keyboard matches the system keyboard:
swift
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
view.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 216) // Standard keyboard height
}
Additionally, I have an inputAccessoryView:
swift
override var inputAccessoryView: UIView? {
return accessoryView
}
The Problem:
When I toggle back to the system keyboard, I get a blank view instead of the default QWERTY keyboard. The accessoryView also disappears.
What I’ve Tried:
Using reloadInputViews() after setting inputView = nil.
Adding delays with DispatchQueue.main.asyncAfter to let the responder state settle.
Ensuring that becomeFirstResponder() is called after resetting inputView.
Debug Information:
view.frame logs show the correct width and height (e.g., 320×216 for an iPhone SE).
self.isFirstResponder returns true after calling becomeFirstResponder().
My Goal:
I want to:
Show the system keyboard (QWERTY) when inputView is reset to nil.
Keep the inputAccessoryView visible at the top.
What am I missing? How can I fix this issue? Any help would be greatly appreciated!
You Don’t need self.reloadInputViews()
, just use the following:
private func showEnglishKeyboard() {
// Reset to system keyboard
self.resignFirstResponder() // Dismiss current keyboard
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.inputView = nil // Reset inputView to default keyboard
self.becomeFirstResponder() // Reactivate input controller
}
}
Additionally you can also do:
private func showEnglishKeyboard() {
// Reset to system keyboard
self.inputView = nil // Reset inputView to default keyboard
self.reloadInputViews() // Reload keyboard
}
Also try to remove these suggestionPanel.isHidden = true accessoryView.isHidden = false
and then test again.
You can find more here