Skip to content

Fix iOS TextInput IME composition issues for CJK languages#56082

Draft
kdwkr wants to merge 1 commit intofacebook:mainfrom
kdwkr:fix/ios-textinput-ime-composition
Draft

Fix iOS TextInput IME composition issues for CJK languages#56082
kdwkr wants to merge 1 commit intofacebook:mainfrom
kdwkr:fix/ios-textinput-ime-composition

Conversation

@kdwkr
Copy link
Contributor

@kdwkr kdwkr commented Mar 13, 2026

Summary:

CJK (Chinese/Japanese/Korean) IME composition on Fabric is broken — the composition underline disappears and composition state is destroyed during input. This affects Japanese, Chinese, and Korean users on the New Architecture and has been reported as a market-blocking issue.

Root causes and fixes:

  1. updateEventEmitter: reapplies defaultTextAttributes every renderRCTWrapEventEmitter creates a new NSData each time, failing isEqualToDictionary:, which triggers [super setDefaultTextAttributes:] and destroys the composition underline. Fix: defer during active markedTextRange, apply after composition ends in textInputDidChange.

  2. _setAttributedString: overwrites text during state round-tripsupdateState: round-trips call _setAttributedString: which replaces attributedText, resetting markedTextRange. Fix: skip when markedTextRange is active; text syncs via textInputDidChange_updateState after composition.

  3. maxLength enforcement blocks IME mid-compositiontextInputShouldChangeText:inRange: enforces maxLength without checking markedTextRange, truncating intermediate CJK input (e.g., Korean ㅎ→하→한). Fix: defer maxLength during composition, enforce via post-composition truncation in textInputDidChange.

  4. textInputDidChangeSelection triggers spurious updates in multilineisEqual: on NSAttributedString fails during composition due to system underline attributes, causing unnecessary textInputDidChange calls. Fix: use .string isEqualToString: for bare text comparison.

Paper (old architecture) is unaffected; these issues are Fabric-only due to synchronous updateEventEmitter:/updateState: calls.

Fixes #48497
Fixes #55257
Fixes #55059

Changelog:

[IOS] [FIXED] - Fix CJK IME composition underline disappearing and composition state being destroyed in Fabric TextInput

Test Plan:

  • XCTest unit tests added in RCTTextInputComponentViewIMETests.mm covering all 4 fixes
  • Both modified files pass standalone clang -fsyntax-only compilation
  • Manual verification: type CJK characters (Japanese/Korean/Chinese) in a <TextInput> on Fabric — composition underline should remain visible and composition should not be interrupted
  • Verify maxLength prop works correctly after CJK composition commits
  • Verify multiline <TextInput> does not fire spurious onChange events during CJK composition

CJK (Chinese/Japanese/Korean) IME composition on Fabric was broken in
multiple ways - the composition underline disappeared and composition
state was destroyed. This was caused by four independent issues:

1. `updateEventEmitter:` reapplied `defaultTextAttributes` every render,
   which destroyed the composition underline. Now deferred during active
   `markedTextRange` and applied after composition ends.

2. `_setAttributedString:` overwrote `attributedText` during state
   round-trips, resetting `markedTextRange`. Now skipped when
   `markedTextRange` is active.

3. `textInputShouldChangeText:inRange:` enforced `maxLength` during
   composition, blocking or truncating intermediate IME input. Now
   deferred until composition commits, with post-composition truncation.

4. `textInputDidChangeSelection` used `isEqual:` on attributed strings,
   which always failed during composition due to system underline
   attributes. Changed to bare text comparison via `isEqualToString:`.

These issues only affected the New Architecture (Fabric); Paper was
unaffected due to its asynchronous bridge timing.

Fixes: facebook#48497
Fixes: facebook#55257
Fixes: facebook#55059
@meta-cla meta-cla bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Mar 13, 2026
@kdwkr kdwkr marked this pull request as ready for review March 13, 2026 08:16
@kdwkr kdwkr marked this pull request as draft March 13, 2026 08:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.

Projects

None yet

1 participant