Like so many other threads here I need to move a view up so its visible while they keyboard is visible and the correct answer seems to be this in most cases:
var isKeyboardVisible = false
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
}
@objc func keyboardWillShow(notification: NSNotification) {
if !isKeyboardVisible {
if let keyboardRectValue = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
let keyboardHeight = keyboardRectValue.height
if self.view.frame.origin.y == 0 {
self.view.frame.origin.y -= keyboardHeight
}
}
isKeyboardVisible = true
}
}
@objc func keyboardWillHide(notification: NSNotification) {
if isKeyboardVisible {
if let keyboardRectValue = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
let keyboardHeight = keyboardRectValue.height
if self.view.frame.origin.y != 0 {
self.view.frame.origin.y += keyboardHeight
}
}
isKeyboardVisible = false
}
}
This however doesn't work if the user uses a custom keyboard.
keyboardHeight
is 0 if a custom keyboard is used. But if the stock keyboard is used the height seems correct.
Can be reproduced if you install Google GBoard and try to get the height of the keyboard.
I'm quite certain I'm not the only one using a custom keyboard, so I guess there should be some kind of solution for this problem which is dynamic and doesn't include a long if/else list.
Addition 1: I found this answer which suggests to add an inputAccessoryView
to the textfield. This makes perfect sense to me as this view will always be exactly above the keyboard. There is how ever two problems with this.
One, content is still being hidden behind the keyboard. Two, if the textfield which is currently focused is behind the keyboard, should I add a duplicate of it to the ´ inputAccessoryView´ so whatever is written is shown in both? This seems like a lot of extra work.
What does apps like whatsapp do to solve this? There must be a universal way to adapt the content to fit above any keyboard (stock or custom) and also not disappear above the top part of the screen!?!?
So this is the cleanest way I've found.
Swift 4.2
Many solutions for getting the the necessary view above the keyboard is to move all the content up and beyond the screen limit. I consider this bad practice there the will be content totally inaccessible to the user outside of the screen as long as the keyboard is visible.
As in my solution above I prefer to adjust the size of the content instead of moving it. So if the content is in a tableview or a scrollview everything will still be available while the keyboard is visible.
If you however prefer that approach just change this line:
for this: