I'd like to achieve a layout similar to the one shown in the Apple Fitness app. When I insert a ScrollView into a TabView, everything works fine, but if I try to add a NavigationStack to wrap the Views, the layout breaks.
This is a simplified version without NavigationStack:
TabView {
//This will be the place for ForEach (For now I use a single ScrollView view)
ScrollView {
Rectangle()
.fill(.red.opacity(0.2))
.frame(height: 2000)
}
.safeAreaPadding(.top, 40)
.scrollBounceBehavior(.basedOnSize, axes: .vertical)
...other dummy views
}
.tabViewStyle(.page(indexDisplayMode: .never))
.background(.purple.opacity(0.2))
.ignoresSafeArea(.all)
.safeAreaInset(edge: .top, spacing: 0) {
Rectangle()
.fill(.green.opacity(0.2))
.frame(height: 120)
.padding(.top, -80)
}
The expected behaviour is that the Scrollview content flows behind the NavigationStack header (and consequently the safeAreaInset content) which is transparent and also flows behind the bottom tab bar (because this View will be contained in another Tabview which represents the main navigation of the app) which is also transparent (liquid glass)
External TabView (Main Navigation):
TabView(selection: $selectedTab) {
Tab("First", systemImage: "", value: 1) {
//FirstView
}
Tab("Second", systemImage: "", value: 2) {
//NewTabView <-- This is where the View will go
}
Tab("Third", systemImage: "", value: 3) {
//ThirdView
}
}
I want to use a TabView and not an horizontal ScrollView because I want to load new tabs when I reach a certain threshold. This behavior works well with the TabView, but when I try to use the horizontal ScrollView, I run into problems with the indexes and the "loadMore" method is called more times than expected
NavigationStack modifiers will be always this:
NavigationStack {
//TabView
}
.navigationBarTitleDisplayMode(.inline) <-- Only inline title
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button("", systemImage: "") {
//action
}
}
}
The following video shows a reconstruction of the above mentioned issue:
Initially the ScrollView works as expected, but if I reach the top of the ScrollView (as seen in the video) or even the bottom in the same way, the ScrollView "jumps" and breaks its constraints, resulting in unexpected behavior
All hardcoded numbers are for question purpose only, simulator used: iPhone 17 Pro Max with iOS 26
TabView
nested inside aNavigationStack
, it needs to be the other way around.