Environment
- iPadOS 26.0 / 26.1 (Simulator: iPad Air 11-inch (M3))
- SwiftUI,
NavigationView+.navigationViewStyle(.stack)(also reproduced conceptually withNavigationStack) - iPad only
Symptom
I have a custom split-style layout built with a plain HStack:
HStack(spacing: 0) {
if showSidebar {
Sidebar().frame(width: 80).transition(.move(edge: .leading))
}
HStack(spacing: 0) {
NavigationStack { MenuList() }.frame(width: 230)
Divider()
NavigationStack { DetailScreen() } // <- this bar is affected
}
}
Toggling showSidebar inside withAnimation changes the x origin of the
right-hand navigation container by 80pt.
After that toggle, the Liquid Glass platter (capsule) behind the navigation bar's leading bar button item is drawn at its previous x position, while the button's glyph is laid out correctly. The capsule and the glyph are visually separated by roughly the amount the container moved. Hit testing follows the glyph, so it is purely a rendering/layout mismatch of the platter background.
Inspecting the view hierarchy, _UINavigationBarPlatterView /
_UINavigationBarPlatterGlassView report a frame that matches the pre-toggle
geometry, i.e. the platter container is not re-laid-out when the hosting
navigation bar's window-space origin changes without its size changing in a
way that triggers a full bar layout pass.
Condition
It only happens on screens where the navigation bar has exactly one
platter group — i.e. a leading item and no trailing items. As soon as the
same screen also has a .topBarTrailing item (so UIKit builds two platters),
the leading platter is positioned correctly after the toggle.
What I tried
.id(...)on the toolbar content to force a rebuild: no effect- adding a zero-size / hidden trailing
ToolbarItem: no effect - calling
setNeedsLayout()/layoutIfNeeded()on theUINavigationBarafter the animation: no effect - disabling the animation: no effect
The only workaround I found is to opt the leading group out of the system platter entirely and draw my own:
ToolbarItemGroup(placement: .topBarLeading) {
button
.frame(width: 44, height: 44)
.glassEffect(.regular.interactive(), in: Circle())
}
.sharedBackgroundVisibility(.hidden)
This fixes the offset, but it has its own downside — see https://developer.apple.com/forums/thread/811012 — the manually drawn glass does not participate in the navigation push/pop morph the system platter does.
Notes
The reproduction appears to be sensitive to the exact geometry / device orientation: a reduced sample I built later did not reproduce it reliably, so I have not been able to attach a minimal project yet. If a DTS engineer wants one, I can keep reducing.
Questions:
- Is a plain HStack-based sidebar (rather than NavigationSplitView) an unsupported configuration for the navigation bar platter, i.e. is the platter's position expected to be invalidated only on size changes?
- Is there a supported way to invalidate the platter layout manually?
- Is .sharedBackgroundVisibility(.hidden) + manual .glassEffect the recommended escape hatch here, or is it expected to break the push/pop transition?