-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
useAnimatedKeyboard fixes (iOS) #6755
base: main
Are you sure you want to change the base?
Conversation
bc78384
to
606096c
Compare
Previously, when the keyboard was detached, useAnimatedKeyboard returned a height corresponding to the height of a docked keyboard. However, when the keyboard is floating, undocked or split, the height should be 0. Listen for the UIKeyboardWillHideNotification notification to determine if the keyboard has been undocked. We must now listen for show and hide notifications instead of UIKeyboardWillChangeFrameNotification, as the show/hide notifications are dispatched after the change frame notification. Adapted from the initial work in software-mansion#5710. Listening for hide is simpler than calculating whether the keyboard is detached, compatible with Stage Manager, and maintains compatibility with interactive keyboard dismissal.
When processing a keyboard frame, if the keyboard did not animate to the target height (e.g. when closing the software keyboard on a device with a physical keyboard), the height would be set to the wrong value in updateKeyboardFrame on the subsequent update. Instead of relying on the measuringView, which refers to the closing animation in such cases, return _targetKeyboardHeight, which is also returned in keyboardWillChangeFrame.
On iOS, when Prefer Cross-Fade Transitions is enabled, the keyboard position and height is reported differently (0 instead of Y position value matching height of the frame.) Override the initial and target keyboard height when this preference is enabled.
The keyboard frame passed to keyboardWillChangeFrame is in the screen's coordinate space [1]. Convert to the window's coordinate space to support Stage Manager. https://developer.apple.com/documentation/uikit/uikeyboardframeenduserinfokey?language=objc
606096c
to
3c2d160
Compare
Hi @mhoran, thanks for another PR! Someone from Reanimated team will review this PR shortly. Would you mind giving us a bit more context on why exactly some of the changes were made (e.g. what's the reason to change |
When the keyboard is dismissed via the close button or is undocked, the interactive dismissal observer will be notified of the geometry change before the show/hide notification is received. Bail out before updating the keyboard height if the reported keyboard height is 0 or if the keyboard is undocked (keyboard width != window width.) Note that this still allows some updates through when they shouldn't be, but it's better than before, especially for floating keyboards.
Sure thing! I tried to leave detailed notes in my commit messages for posterity, but happy to provide further context as well. Regarding I found that the most reliable way to determine if the keyboard has been detached is to listen for However, this approach also has the benefit of simplifying the logic in the change handler. I was able to remove the logic that tried to guess whether the keyboard was opening or closing -- which I found to be inaccurate at times, especially when a hardware keyboard is attached (due to the autosuggest dock.) The I fixed a few more issues along the way.
There is a new API, Keyboard Layout Guide, which will make this all a lot simpler in the future. However, it was introduced in iOS 15. So we will have to live with this complexity until RN 0.76 is the oldest supported version for Reanimated. Note that there remain some issues with undocked and split keyboard modes, due to incorrect start frame positions sent in notifications. Apple has removed these modes in new devices, so I didn't try to implement workarounds. |
Here is a screen recording showing the improvements: https://drive.google.com/file/d/1EFDhYZWNMXhJIwNlj1_ugeVwe3FqZqVF/view?usp=drivesdk. |
ddefb46
to
b6c8364
Compare
It seems I may also have fixed #6727 as I was cleaning things up in 9f6b546. When a hardware keyboard is connected and the autocorrect bar is on screen, the keyboard is considered "open". But when you show the on screen keyboard, it rapidly hides and then shows the keyboard -- inadvertently triggering the interactive dismissal logic. Cleaning up the interactive dismissal flags fixed this for the hardware keyboard case, and I believe it should fix the scenario described in #6727 as well. |
bc3d884
to
22aee6a
Compare
I tested this in my app and can confirm it does fix the Prefer Cross Fade Transition issue (#6440) |
22aee6a
to
bc3d884
Compare
There is an issue with iOS 18.2 when opening the on-screen keyboard from the autosuggest bar when a hardware keyboard is attached. Opening the on-screen keyboard in this way will not properly update the height returned by |
bc3d884
to
0c778e8
Compare
The interactive dismissal logic would get tripped up if the keyboard was rapidly opened and closed, which can happen if a hardware keyboard is used and the autosuggest dock appears and then disappears when the on screen keyboard is opened. Fixes software-mansion#6727.
0c778e8
to
9f6b546
Compare
I managed to fix the iOS 18.2 hardware keyboard issue by updating the keyboard height in response to This has cleaned up keyboard state handling as well. Now state changes are handled only by the corresponding notification handlers, and On a side note, I managed to get the |
UIKeyboardDidShowNotification on iOS 18.2 returns an incorrect end frame origin when opening the on-screen keyboard with a hardware keyboard attached. Instead of relying on this incorrect frame, return the height of the keyboard view in response to UIKeyboardDidShowNotification and 0 in response to UIKeyboardDidHideNotification. State changes are now completely handled in response to notifications, and updateKeyboardFrame is only responsible for animation tracking.
7c9a7c0
to
5a6a72f
Compare
Summary
fix: return correct height for detached keyboard on iOS (fixes #5584)
fix: don't clobber keyboard height when keyboard did not animate on iOS
fix: support cross-fade transitions in useAnimatedKeyboard on iOS (fixes #6440)
fix: convert keyboard position to window coordinate space on iOS (Stage Manager compatibility)
fix: don't prematurely update keyboard height during dismissal on iOS
fix: don't jump to height when iOS keyboard is rapidly opened/closed (fixes #6727)
Test plan
Can be tested with the useAnimatedKeyboard example.