fix(tips): raise the post-tip keyboard from UIKit instead of @FocusState - #527
Merged
Conversation
The post-tip open (#524) set the composer's SwiftUI @focusstate on appear. That updates SwiftUI's focus state — the caret and the isComposing bar-morph — but never presents the system keyboard, because the composer is hosted inside a nested UIHostingController bridged through UIKit (ChatScreenRepresentable → ChatScreenViewController). A programmatic @focusstate doesn't cross that hosting boundary; only a real becomeFirstResponder does. Taps worked because a tap is a real UIKit responder event. Bumping the .task delay would never have helped — every working focus-on-appear in the app is a pure-SwiftUI screen. Raise the keyboard from the UIKit layer that already owns keyboard behavior: ChatScreenViewController.viewDidAppear (the point the push transition has settled) calls becomeFirstResponder() on the composer field, guarded so it's a strict once-per-open. Removes the @FocusState/.task focus hack and its plumbing through ConversationBottomBar/ConversationComposer. The isComposing morph still works — when the keyboard rises SwiftUI syncs @focusstate and the existing onChange(of: isFocused) fires.
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.
Problem
After #524, completing a tip opened the chat but only focused the message field — the keyboard never came up.
Root cause
#524 set the composer's SwiftUI
@FocusState = trueon appear. That updates SwiftUI's focus state — the caret and theisComposingbar-morph, which is why the field looked focused — but it does not present the system keyboard. The composer lives inside a nestedUIHostingControllerbridged through UIKit (ChatScreenRepresentable→ChatScreenViewController), and a programmatic@FocusStatedoesn't cross that hosting boundary. Only a realbecomeFirstResponderdoes — which is why tapping the field (a genuine UIKit responder event) always raised the keyboard.Every working focus-on-appear in the app (
EnterPhoneScreen,LoginScreen, etc.) is a pure-SwiftUINavigationStack/sheet screen — some raise the keyboard with only a 100 ms delay, mid-transition. So the 350 ms.taskdelay was never the issue; the hosting boundary was, and no amount of extra delay would have fixed it.Fix
Raise the keyboard from the UIKit layer that already owns keyboard behavior (per
ChatScreenViewController's own doc: "All scroll, keyboard, and flow-under behavior lives in the UIKit screen"):ChatScreenViewController.viewDidAppear— the exact moment the push transition has settled — callsbecomeFirstResponder()on the composer's text field.didFocusComposerflag → strict once-per-open (tighter than the old.task, which could re-fire on re-appear).@FocusState/.taskfocus hack and itsfocusOnAppearplumbing throughConversationBottomBar/ConversationComposer.isComposingbar-morph is preserved — when the keyboard rises, SwiftUI syncs@FocusStateand the existing.onChange(of: isFocused)fires.The
.tipConversationWithKeyboardroute andopenKeyboard→focusOnAppear→focusesComposerOnAppearchain are unchanged; only the mechanism that acts on the flag moved from SwiftUI to UIKit.Testing
./Scripts/build.sh --device→ BUILD SUCCEEDED