ARTICLE AD BOX
If you want the content of the nested (paged) TabView to scroll behind the tab bar of the parent TabView then you just need to apply .ignoresSafeArea(edges: .bottom) to the nested one.
However, when you do this, the page indicators (the dots) for the nested TabView move into the safe area inset and disappear behind the tab bar image of the parent TabView.
My answer to SwiftUI - TabView Safe Area provides a workaround for the issue with the dots. The workaround is to disable the native dots and to display custom dots instead, using an overlay. This also means supplying a binding to the nested TabView, for tracking the selected tab.
Below is an example to show it all working, adapted from the code in the question.
struct ContentView: View { struct Item: Identifiable { let id = UUID() let label: String } let items: [Item] = [ .init(label: "One"), .init(label: "Two"), .init(label: "Three")] // @State private var tabbarVisible: Visibility = .visible @State private var selectedPage = 0 var body: some View { TabView { TabView(selection: $selectedPage) { ForEach(Array(items.enumerated()), id: \.offset) { offset, item in List { ForEach(items) { item in Button { // addItem() } label: { // Text(item.timestamp!, formatter: itemFormatter) Text(item.label) .frame(height: 280) .frame(maxWidth: .infinity) .background(.yellow, in: .rect(cornerRadius: 16)) } .alignmentGuide(.listRowSeparatorLeading) { dim in dim[.leading] } } // .onDelete(perform: deleteItems) } .tag(offset) } } .ignoresSafeArea(edges: .bottom) .tabViewStyle(.page(indexDisplayMode: .never)) .overlay(alignment: .bottom) { // See https://stackoverflow.com/a/78472742/20386264 PageDots(nPages: items.count, currentIndex: selectedPage) } // .onAppear() { // withAnimation { // tabbarVisible = tabbarVisible == .visible ? .hidden : .visible // // } // } .tabItem { Label("Items", systemImage: "list.dash") } } .tabViewStyle(.tabBarOnly) } }
