Bugfix: Stabilize NavigationStack Layout + Reduce NavigationBar Spacing on Sheets#475
Bugfix: Stabilize NavigationStack Layout + Reduce NavigationBar Spacing on Sheets#475fhasse95 wants to merge 1 commit into
Conversation
|
This code is extremely finicky, and has tests all over the showcase. I think it would help for you to list out exactly which playgrounds you tested and how. One that you didn't explicitly call out is the SafeArea playground --> Geometry padding playground, which has facilities for hiding and showing the Navigation Bar, both with and without a sheet. |
Yes, I totally agree. Since this code is central and used in many places, I wanted to be extra careful. That's why I tried out the changes in various scenarios. In Skip Showcase, I validated the changes using the following playgrounds:
During implementation, I first tested the changes in my own app across a variety of scenarios, refining the implementation iteratively based on my observations. Besides fixing the original issue, I specifically looked at things like switching between tabs, verifying the initial layout pass of the navigation bar, and the layout behavior of sheets and full-screen covers. I also made sure that neither the navigation bar nor the underlying content jumped during transitions. Most of my testing was done on my Google Pixel 9, where I also verified gesture-driven interactions, such as slowly dismissing a sheet using the back gesture, to ensure the navigation bar behaves correctly throughout the interactive transition. Once everything looked good there, I built Skip Showcase against my local SkipUI branch and went through all of the playgrounds above. To make sure I hadn't introduced any regressions, I repeatedly switched between my bugfix branch and the current That said, I obviously can't completely rule out that I may have missed an edge case. So please feel free to try it with either your own app(s) or with Skip Showcase, and let me know if you spot anything that doesn't look right 😊 |
This PR stabilizes
NavigationStacklayout behavior so that the navigation bar and the content below it no longer jump when the navigation bar height is measured or updated.Before this change, the navigation bar could be laid out with an initial height of zero or an incomplete height, and then expand to its final size after the first layout/measurement pass. Visually, this made the navigation bar appear collapsed immediately after a tab switch and then "slide" or jump into place once layout completed.
In release builds with simple views this is often hard to notice because the layout pass completes very quickly. With more complex views, or in debug builds, however, the intermediate state becomes visible. This is also reproducible in the Skip Showcase app in a debug build when taking a closer look.
To reproduce this in the Skip Showcase app:
AbouttabShowcasetabShowcaseviewNote: The jump only happens during the first layout of that view. After the
Showcasetab has been laid out once, switching away and back again usually does not reproduce the issue since the navigation bar has already been measured.Below is a before/after comparison of this example in the Skip Showcase app, slowed down to make the issue easier to see:
Before:

After:

As shown above, before the change, the navigation bar is initially collapsed after switching tabs and becomes visible only after layout catches up. After the change, the navigation bar is present at the correct size immediately.
This is achieved by reserving an estimated top-bar height before the first real measurement is available. Once the actual top-bar size has been measured, the layout switches to the measured value. This keeps the content and navigation bar stable during initial layout and prevents the visible jump.
I also manually verified additional cases that previously showed navigation-bar jumps during initial layout, including
NavigationStackinside.sheetand.fullScreenCover, using my own Skip app with more complex views and navigation flows. Those cases are also fixed with this change.As part of the same layout improvements, this PR also reduces unnecessary empty space between the navigation bar and the top edge of sheets, making better use of the available sheet area:
Large Title (Before / After):


Inline Title (Before / After):


Thank you for contributing to the Skip project! Please review the contribution guide at https://skip.dev/docs/contributing/ for advice and guidance on making high-quality PRs.
Use this space to describe your change and add any labels (bug, enhancement, documentation, etc.) to help categorize your contribution.
Skip Pull Request Checklist:
swift testI used Codex to iteratively investigate and refine the fix for the NavigationStack layout issue. To verify the results, I tested multiple playground views in the Skip Showcase app and my own Skip app, which contains several navigation scenarios, including sheets, full-screen covers, tab bars, and nested navigation. All of these scenarios work properly after the bug fix.