-
-
Notifications
You must be signed in to change notification settings - Fork 55
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
[IOS] Incorrect behavior of hooks and components when focusing on an input with secureTextEntry enabled. #327
Comments
Have the same issue. |
Same issue |
Interesting, I think this bug was introduced in iOS 17. A similar issue was raised quite long time ago: #243 But I'll have a look on it 👀 |
Thank you, as this is a critical issue for working with animations. If we take into account useKeyboardHandler, KeyboardAvoidingView can be replaced with the one from the "react-native" package (for iOS for now).🤞 This library is the only one that truly helps interact with the keyboard for animations. The rest are too buggy. 😅 |
@kirillzyusko at the moment when glitches occur in KeyboardAvoidingView, in the logs for useKeyboardHandler, you can observe the following:
|
Yes @A-Yatsyk If you add LOG onStart {"duration": 250, "eventName": "onKeyboardMoveStart", "height": 291, "progress": 1, "target": 473}
LOG keyboardWillShow 291
LOG onStart {"duration": 250, "eventName": "onKeyboardMoveStart", "height": 336, "progress": 1, "target": 473}
LOG keyboardWillShow 336 The thing is that I can not filter out bad event from a native code and I have to propagate it to JS 😔 The bug was actually in If I change interpolation mechanism, then we'll see an expected output, because these 2 events are emitted after each other and we'll interpolate to las frame (i. e. from 0 to 336). So in #331 I'm fixing
Got you. I will try to experiment more to see why these glitches actually happen (I know it's because of duplicated events, but will try to find a way to ignore them somehow)... P. S. such glitch happens because in LOG onStart {"duration": 250, "eventName": "onKeyboardMoveStart", "height": 291, "progress": 1, "target": 1377} 1705151792325
LOG 0 [0, 291]
LOG {"bottomHeight": 0}
LOG keyboardWillShow 291
LOG keyboardWillShow 291
LOG onEnd {"duration": 250, "eventName": "onKeyboardMoveEnd", "height": 291, "progress": 1, "target": 1377} 1705151792333
LOG 291 [0, 291]
LOG {"bottomHeight": 139}
LOG onStart {"duration": 250, "eventName": "onKeyboardMoveStart", "height": 336, "progress": 1, "target": 1377} 1705151792335
LOG 291 [0, 336]
LOG {"bottomHeight": 159.35714285714286}
LOG keyboardWillShow 336
LOG keyboardWillShow 336
LOG 45.18494185101008 [0, 336]
LOG {"bottomHeight": 24.744134823172185} |
@kirillzyusko yes, thanks, I understand, although it's actually strange that there is an onEnd callback indicating that the keyboard was opened with a height of 291, even though that's not the case, and an update is occurring. |
It would be good to find a way to fix this for KeyboardAvoidingView at least. |
## 📜 Description Fixed choppy animation for `KeyboardAvoidingView` if child `TextInputs` are using `secureTextEntry` property. ## 💡 Motivation and Context The problem which causes jumpy behavior is hidden in fact, that 2 `keyboardWillShow` + `keyboardWillHide` events are emitted instead of a single one. If we add logger we'll see: ```bash onStart height 291 onEnd height 291 onStart height 336 ... // onMove onEnd height 336 ``` And such events are very similar to what happens on Android when keyboard gets resized. So basically fix consist from two parts. ### Part 1️⃣ In `useKeyboardInterpolation` we are not using Android specific interpolation and are using "progress"-based animation (interpolation between current keyboard frame and final keyboard frame). It allows us to have positive value and make animation smooth. However is some cases we may see a jump occurring for one frame, and for that we apply second fix. ### Part 2️⃣ In second part we are handling "unnecessary" `onEnd` event. Before we were simply updating `height`/`progress` values in `onEnd` handler - it was needed to handle cases when `onMove` handler is not called but we still need to synchronize the state. In this PR I slightly re-worked approach and now I'm updating it only if `duration === 0` (i. e. transition was instant). Closes #327 ## 📢 Changelog <!-- High level overview of important changes --> <!-- For example: fixed status bar manipulation; added new types declarations; --> <!-- If your changes don't affect one of platform/language below - then remove this platform/language --> ### JS - use "progress"-based interpolation for iOS in `useKeyboardInterpolation`; - update values in `onEnd` only if `duration` is `0`. ## 🤔 How Has This Been Tested? Tested on iPhone 15 Pro. ## 📸 Screenshots (if appropriate): |Before|After| |-------|-----| |<video src="https://github.com/kirillzyusko/react-native-keyboard-controller/assets/22820318/b75f7ca4-fa84-448d-92f8-517b5886b84e">|<video src="https://github.com/kirillzyusko/react-native-keyboard-controller/assets/22820318/fe3b5cf0-8a61-4af6-ac75-ae3ce64cca72">| ## 📝 Checklist - [x] CI successfully passed - [x] I added new mocks and corresponding unit-tests if library API was changed
@A-Yatsyk I pushed a PR with a fix into Thank you for you help in debugging this issue, active participation in resolution and the creation of such descriptive issue ❤️ |
Thank you for the prompt resolution of the issue, the problem has been resolved 👍 |
Describe the bug
When focusing on a field with secureTextEntry set to true (iOS only), UI misbehaves with KeyboardAvoidingView, causing erratic jumping. In useKeyboardHandler, onStart will be called with progress 1, followed immediately by onEnd with progress 1, and only after these (prior onStart and onEnd) will correct calls of onStart, onMove, and onEnd occur.
This behavior is also observed in KeyboardEvents, where the first listener is wrong, and only after that, do true listener calls follow.
A similar issue was present in React-Native itself, but it was fixed since KeyboardAvoidingView in React-Native now works as expected for iOS (e.g., facebook/react-native#39411).
Code snippet
To Reproduce
Steps to reproduce the behavior:
OR
Expected behavior
Expected behavior should be the same as when the secureTextEntry is set to false
Screenshots
Screen.Recording.2024-01-12.at.14.48.41.mov
Smartphone:
The text was updated successfully, but these errors were encountered: