fix(ios): multiline inputs must insert a newline on every keyboard - #42
Open
JeremieMercier wants to merge 1 commit into
Open
fix(ios): multiline inputs must insert a newline on every keyboard#42JeremieMercier wants to merge 1 commit into
JeremieMercier wants to merge 1 commit into
Conversation
A vertical-axis TextField drops focus on Return from a hardware keyboard (simulator driven from the Mac, iPad + external keyboard) instead of inserting a line break — as-designed per Apple DTS (developer.apple.com/forums/thread/760511), and no modifier combination opts out. Soft keyboards inserted the newline, hardware ones never could. Rebuild the multiline branch of NativeUITextInputCore on TextEditor, whose return key inserts a line break on every keyboard: - an invisible Text mirror re-creates the auto-growing lineLimit(min...max) window (same clamps, same default cap of 5), hidden from VoiceOver so typed text isn't read twice - placeholder recreated as an overlay (TextEditor has no slot), UITextView container padding pulled back so text lines up with the single-line variants inside the same chrome - scrollContentBackground(.hidden) keeps the variant chrome's background submitLabel/onSubmit now attach to single-line fields only: multiline Return always inserts a newline and @submit is send-button-only, matching what Android multiline (Enter = newline, no keyboard submit) always did. Value sync, echo prevention, sync modes, max_length, keyboard type and the iOS 18 selection binding are unchanged and apply to TextEditor as-is. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
The bug
On iOS, a
multilinetext input (<native:outlined-text-input multiline …>, and the filled/bare variants) never inserts a line break when Return is pressed from a hardware keyboard — the simulator driven from the Mac keyboard, or an iPad with an external keyboard. The field silently drops focus instead. Soft (on-screen) keyboards were unaffected. Android has always behaved correctly (Enter inserts a newline).Root cause
The multiline branch of
NativeUITextInputCorewas aTextField(axis: .vertical). SwiftUI's vertical-axisTextFieldunfocuses on hardware-keyboard Return by design — confirmed by Apple DTS in https://developer.apple.com/forums/thread/760511 — and no modifier combination opts out (.onKeyPressinterception also unfocuses). Removing.onSubmitis not enough.The fix
Rebuild the multiline branch on
TextEditor(UITextView-backed), whose return key inserts a line break on every keyboard — the alternative Apple suggests in that thread:Textmirror re-creates the auto-growinglineLimit(min...max)window the vertical TextField had (same clamps, same default cap of 5 lines); it isaccessibilityHiddenso VoiceOver doesn't read the typed text twice.TextEditorhas no placeholder slot), with UITextView's internal container padding pulled back so typed text lines up with the single-line variants inside the same chrome.scrollContentBackground(.hidden)lets the variant chrome keep painting the background..submitLabel/.onSubmitnow attach to single-line fields only. Multiline Return always inserts a newline and@submitis send-button-only — matching what Android multiline (Enter = newline, no keyboard submit) has always done. Documented onBaseTextInput::multiline()and in the core's header.Value sync, echo prevention, the three
sync_modepolicies,max_length, keyboard type, disabled/read-only, custom fonts and the iOS 18selection:binding (@selectionChange) are unchanged and apply toTextEditoras-is. Single-line fields keep a byte-for-byte identical code path. No wire/PHP behavior change; Android untouched.Verification
swiftc -parseclean; full simulator build succeeds and the rebuilt app was manually tested: multiline fields accept newlines from both the Mac keyboard (simulator) and the on-screen keyboard; single-line@submit+keep-focus-on-submitchat pattern unchanged.multiline,min_lines,max_linesserialize as before).🤖 Generated with Claude Code