I have a project that contains a UIScrollView
and many UITextField
inside it.
For the first time I select a UITextField
, UIKeyboardWillShowNotification
is called, which is fine. But whenever I select new UITextField
(THE KEYBOARD IS STILL THERE), UIKeyboardWillShowNotification
is called again !!!, which is weird.
I also set a symbolic breakpoint for [UIResponder resignFirstResponder]
and I see that it is hit before and after UIKeyboardWillShowNotification
is called !!!
The other thing is that UIKeyboardWillHideNotification
is only called when I hit the "Done" button on the keyboard
I'm sure to not call any resignFirstResponder
, becomeFirstResponder
, endEditing
anywhere. (I mean not call wrongly)
What can cause this problem ?
Here is the stacktrace
To workaround the problem, I used the following code to cancel the
UIKeyboardWillShowNotification
callback if the keyboard's frame is not changing.For Swift 3/4:
The best approach is to Add notification & remove it once your purpose is solve.
like this .
Now write your code for movement of views & textField in
keyboardWillShow
& revert them back to position inkeyboardWillHide
methods.Also remove the observers
You can also resign the responder when you press
return
key.That should solve your issue.
The problem is I set
inputAccessoryView
for theUITextField
, and this causeUIKeyboardWillShowNotification
being called again when newUITextField
is selectedThis article Working With Keyboard on iOS explains this well
Whenever new
UITextField
is selected, the OS needs to compute the frame for the keyboard again, and the following notifications are postedThe same applies for when the TextField loses its first responder status
Note that using the same View for
inputAccessoryView
will causeUIKeyboardWillShowNotification
only called onceFor those not using inputAccessoryView but are still having problems, it may be due to using sensitive (password) fields. See this Stackoverflow post and answer: keyboardWillShow in IOS8 with UIKeyboardWillShowNotification
In general I find that many things can cause spurious
UIKeyboardWillShow
andUIKeyboardWillHide
notifications. My solution is to use a property to track whether the keyboard is already showing:Those guards block exactly the spurious notifications, and all is well after that. And the
keyboardShowing
property can be useful for other reasons, so that it is something worth tracking anyway.I have struggled with this, after half a day of searching around and experimenting I think this is the shortest and most reliable code. It is a mix of a number of answers most of which I forget where I found (parts of which are mentioned here).
My problem was a WKWebView which (when the user changed fields) would spawn a load of WillShow, WillHide, etc notifications. Plus I had problem with the external keyboard which still has the onscreen touch bar thing.
This solution uses the same animation code to "Open" and "Close" the keyboard, it will also cope with external keyboard being attached and custom keyboard views.
First register for the UIKeyboardWillChangeFrameNotification.
Then you simply need to map the changes to your view in however you do it (change a hight or bottom constraint constant).
The Animation to Option conversion seems to work (I can only find examples of it being used and not how/why), however, I am not convinced it will stay that way so it may be wise to use a "stock" option. It seems that the Keyboard uses some none specified Animation.