I'd like to update the UIKeyboardAppearance
within a ViewController
. By this I mean let's say the VC loads with UIKeyboardAppearance.default
. If I press a button, I'd like the keyboard to update to .dark
and have the keyboard now show in that same VC as .dark
.
As far as I can tell, iOS checks the value for UIKeyboardAppearance
while loading the VC, and doesn't check again until it loads the VC again. Even if you change the value of UIKeyboardAppearance
and hide/show the keyboard.
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// creating a simple text box, and making the placeholder text the value of the keyboardAppearance
myTextBox.backgroundColor = UIColor.lightGray
myTextBox.frame = CGRect(x: 30, y: 200, width: 300, height: 50)
view.addSubview(myTextBox)
UITextField.appearance().keyboardAppearance = .dark
myTextBox.becomeFirstResponder()
myTextBox.placeholder = "Keybaoard Appearance is: \(UITextField.appearance().keyboardAppearance.rawValue)"
// a simple button to toggle the keyboardAppearance
toggleButton.frame = CGRect(x: 30, y: 300, width: 300, height: 50)
toggleButton.setTitle("Toggle Keyboard", for: .normal)
toggleButton.backgroundColor = UIColor.red
toggleButton.addTarget(self, action: #selector(toggleButtonFunction), for: .touchUpInside)
view.addSubview(toggleButton)
}
// toggles the keyboardAppearance. Hides the keyboard, and a second later shows it again.
@objc func toggleButtonFunction() {
if UITextField.appearance().keyboardAppearance == .dark {
UITextField.appearance().keyboardAppearance = .default
}
else {
UITextField.appearance().keyboardAppearance = .dark
}
myTextBox.resignFirstResponder()
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1), execute: {
self.myTextBox.becomeFirstResponder()
self.myTextBox.placeholder = "Keybaoard Appearance is: \(UITextField.appearance().keyboardAppearance.rawValue)"
})
}
let myTextBox = UITextField()
let toggleButton = UIButton()
}
I was hoping that after changing the UIKeyboardAppearance
and hiding/showing the keyboard it would show with the new appearance ( .dark
or .default
), but it continually shows with the same appearance until the VC is loaded again. You can see the value of UIKeyboardAppearance
changes, but iOS seems to not check for that update until the VC loads again.
Is there any way to force a recheck within a VC?
Thanks for your help!
You can change the keyboard appearance of all text fields recursively on your screen (the allSubviewsOf(type:)
extension is from this great answer by Mohammad Sadiq ):
func changeTextFieldKeyboardAppearance() {
UITextField.appearance().keyboardAppearance = .dark
let textFields = view.allSubviewsOf(type: UITextField.self)
let firstResponder = textFields.first { $0.isFirstResponder }
firstResponder?.resignFirstResponder()
textFields.forEach { $0.keyboardAppearance = .dark }
firstResponder?.becomeFirstResponder()
}
[...]
extension UIView {
func allSubviewsOf<T: UIView>(type: T.Type) -> [T] {
var all = [T]()
func getSubview(view: UIView) {
if let aView = view as? T {
all.append(aView)
}
guard !view.subviews.isEmpty else {
return
}
view.subviews.forEach{ getSubview(view: $0) }
}
getSubview(view: self)
return all
}
}
If your view controller is embedded in a UITabBarController
, you can trigger an update by changing its selectedIndex
and changing it back to the original index immediately:
guard let tabBarController = tabBarController else {
return
}
let selectedIndex = tabBarController.selectedIndex
UITextField.appearance().keyboardAppearance = .dark
tabBarController.selectedIndex = selectedIndex == 1 ? 0 : 1
tabBarController.selectedIndex = selectedIndex
Thanks to Tamás for the answer!
It led me down the path to discover what I needed.
It looks like if you change the keyboardAppearance for UITextField
UITextField.appearance().keyboardAppearance = .dark
the system only checks on VC load. If you change it for each textField
myTextBox.keyboardAppearance = .dark
the system will check each time firstResponder changes and load the correct keyboard.
Thanks again Tamás!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.