Repository navigation
fix(ios): keep a keystroke from repeating what a textChange listener wrote - #11443
Merged
Merged
Conversation
…wrote `TextField`'s `shouldChangeCharactersInRange` delegate raised `textChange` with the typed result and then returned `true`, so when a listener set a different `text` during that event (a formatter, a cap, a reset) the setter pushed that value to the native field and UIKit inserted the typed character on top of it: typing `b` into a field an uppercasing handler had left at `A` showed `ABb` for a property value of `AB`. Every framework whose state applies synchronously inside the event hit it; `TextView` did not, because its delegate reports after the edit is applied. The delegate now returns `false` when the listener wrote a different `text`, as the `valueFormatter` path already does, so the native field keeps the listener's value.
|
View your CI Pipeline Execution ↗ for commit 9620822
💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗ ☁️ Nx Cloud last updated this comment at |
commit: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR Checklist
What is the current behavior?
On iOS,
TextField.textFieldShouldChangeCharactersInRangeReplacementStringcomputes the typed result, raisestextChangethroughtextProperty.nativeValueChange, and then returnstrue. If atextChangelistener sets a differenttextinside that event,Property.setpushes the new value to the native field right away, and UIKit then inserts the typed character on top of it. Typingbinto a field an uppercasing handler had left atAshowsABbwhile the property readsAB; a handler that resets or caps the value sees the rejected character appear anyway.This is not framework-specific. Any integration whose state update runs synchronously inside the native event (Angular change detection in the zone task, Solid and Svelte signals, Octane, plain
textChangehandlers) hits it; integrations that flush asynchronously (Vue's scheduler, React 18 batching) instead see the caret jump to the end after the transformed write lands. Surfaced through nativescript-community/octane#3 while verifying a controlled-input fix there.TextViewis unaffected because its delegate reports after the edit is applied, and Android'sTextWatcherdoes too.What is the new behavior?
After raising
textChange, the delegate returnsfalsewhen the listener wrote a differenttext: the setter has already put that value in the native field, so nothing is applied on top. ThevalueFormatterbranch already worked this way. A listener that leavestextalone, or writes the same value, changes nothing (the write is a no-op in core and the delegate still returnstrue).Tests
apps/automatedgainstypeCharacterNatively, which delivers one keystroke the way UIKit does (ask the delegate, apply the replacement only if it agrees;appendon Android), andtestTextWrittenByTextChangeListenerIsNotRepeatedByTheKeystroke, an uppercasingtextChangelistener typedathenb, assertingABon both the property and the native field. It is gated to iOS since only that delegate can apply a keystroke after the listener ran.Full automated iOS suite on the simulator: 1817 OK, 0 failed with the fix; with only the core change stashed, the same suite fails exactly this test (
Actual: <AAB>), so it guards the regression.