Updated findings
- This does not reproduce in the stock Stream demo app.
- The issue appears when stock
ChatChannelView is embedded under a root TabView that uses iOS 26 tabViewBottomAccessory.
- The same class of regression can also be triggered by applying
.toolbar(.hidden, for: .tabBar) on the pushed channel screen.
- If chat bypasses the accessory shell and we do not hide the tab bar from the channel screen, the layout looks correct.
- So this now looks less like a generic “floating composer always reserves space” bug and more like a compatibility issue between
ChatChannelView's floating composer layout and Apple’s new tab accessory / tab-bar visibility environment.
What did you do?
- Presented stock
ChatChannelView full-screen in SwiftUI.
- Used
composerPlacement = .floating.
- Tested on the current Stream v5 beta line (
develop branch revisions listed below).
- Reproduced inside a host app whose root
TabView uses iOS 26 tabViewBottomAccessory.
- Also tested the same host flow with
.toolbar(.hidden, for: .tabBar) on the pushed channel screen.
- Compared against the stock Stream demo app and against a host configuration where chat bypasses the accessory shell.
What did you expect to happen?
- With
composerPlacement = .floating, the newest message should rest directly under the visible floating composer chrome, without a persistent reserved bottom band.
- The composer should still remain correctly positioned above the keyboard.
ChatChannelView should coexist with tabViewBottomAccessory just as it does in a normal tab/push setup.
What happened instead?
- In the accessory-hosted configuration, the transcript keeps an extra bottom band/gap under the latest message.
- Hiding the tab bar on the pushed channel screen with
.toolbar(.hidden, for: .tabBar) can trigger the same class of regression.
- If the host forces
.ignoresSafeArea(edges: .bottom) to remove the band, the keyboard can cover the composer.
- If chat bypasses the accessory shell, the gap disappears.
Current findings
MessageListConfig.handleTabBarVisibility alone is not the fix.
- This is not fundamentally caused by modal vs push navigation.
- This is not caused by our extra wrapper chrome; a slimmed-down wrapper still reproduces if chat is routed through the accessory shell.
- During SDK-side instrumentation,
tabViewBottomAccessoryPlacement was nil from inside ChatChannelView during the bad host repro, so detecting accessory presence from that environment alone may not be sufficient.
- We also observed cases where the floating transcript inset tracked the raw measured composer container height (
76pt) rather than the visible overlap (48pt), suggesting the composer/list inset logic may be sensitive to container state and/or padded composer measurements in this environment.
Minimal repro shape
- App root has a
TabView.
TabView applies tabViewBottomAccessory.
- One tab contains Stream channel list and pushes into stock
ChatChannelView.
ChatChannelView uses composerPlacement = .floating.
- Observe extra space under the floating composer.
- Remove the accessory or bypass it for chat, and the gap disappears.
GetStream Environment
GetStream Chat version: v5 beta line from develop
GetStream Chat frameworks: StreamChat, StreamChatSwiftUI
iOS version: iOS 26.4
Swift version: Apple Swift 6.3
Xcode version: Xcode 26.4
Device: iPhone 17 Simulator
Additional context
composerPlacement = .floating
- Exact revisions in our repro:
StreamChatSwiftUI: d46ad84161a8d69f913fd160c5a707e6afb244c4
StreamChat: dd9866b59db06bcadca614892b2ed006297ac73b
- These
develop revisions are ahead of the 5.0.0-beta tag, so this repro is on the current v5 beta line rather than the exact beta tag.
- Current local workaround: bypass the shell modifier that applies
tabViewBottomAccessory for chat, keep handleTabBarVisibility enabled, and avoid .toolbar(.hidden, for: .tabBar) on the channel screen.
- This now appears upstream-relevant as a compatibility issue between Stream’s floating composer layout and Apple’s iOS 26 tab accessory / tab-bar visibility model, rather than just a missing public underlap hook.
Updated findings
ChatChannelViewis embedded under a rootTabViewthat uses iOS 26tabViewBottomAccessory..toolbar(.hidden, for: .tabBar)on the pushed channel screen.ChatChannelView's floating composer layout and Apple’s new tab accessory / tab-bar visibility environment.What did you do?
ChatChannelViewfull-screen in SwiftUI.composerPlacement = .floating.developbranch revisions listed below).TabViewuses iOS 26tabViewBottomAccessory..toolbar(.hidden, for: .tabBar)on the pushed channel screen.What did you expect to happen?
composerPlacement = .floating, the newest message should rest directly under the visible floating composer chrome, without a persistent reserved bottom band.ChatChannelViewshould coexist withtabViewBottomAccessoryjust as it does in a normal tab/push setup.What happened instead?
.toolbar(.hidden, for: .tabBar)can trigger the same class of regression..ignoresSafeArea(edges: .bottom)to remove the band, the keyboard can cover the composer.Current findings
MessageListConfig.handleTabBarVisibilityalone is not the fix.tabViewBottomAccessoryPlacementwasnilfrom insideChatChannelViewduring the bad host repro, so detecting accessory presence from that environment alone may not be sufficient.76pt) rather than the visible overlap (48pt), suggesting the composer/list inset logic may be sensitive to container state and/or padded composer measurements in this environment.Minimal repro shape
TabView.TabViewappliestabViewBottomAccessory.ChatChannelView.ChatChannelViewusescomposerPlacement = .floating.GetStream Environment
GetStream Chat version: v5 beta line from
developGetStream Chat frameworks: StreamChat, StreamChatSwiftUI
iOS version: iOS 26.4
Swift version: Apple Swift 6.3
Xcode version: Xcode 26.4
Device: iPhone 17 Simulator
Additional context
composerPlacement = .floatingStreamChatSwiftUI:d46ad84161a8d69f913fd160c5a707e6afb244c4StreamChat:dd9866b59db06bcadca614892b2ed006297ac73bdeveloprevisions are ahead of the5.0.0-betatag, so this repro is on the current v5 beta line rather than the exact beta tag.tabViewBottomAccessoryfor chat, keephandleTabBarVisibilityenabled, and avoid.toolbar(.hidden, for: .tabBar)on the channel screen.