When I put a NavigationStack in a TabView in SwiftUI, the child views have improper spacing at the top of each view. This only happens when I move to another tab and return back. Also it only occurs when I initialize TabView with TabView(selection: selectedTab).
Does anyone know why this happens, if it's a known bug/if it's my own issue, or how to fix it?
The undesired view looks like this: Child view with improper spacing at top
The expected view looks like this: Expected view
It looks like it is ignoring the toolbar at the top. Also, the reason I need a NavigationStack with the TabView selection is because I want to be able to pop to the root view whenever I tap the tab a second time. If there's another approach to this without the selector or without NavigationStack, that would be great too.
My code for my TabView is attached here:
//
// WorkoutTabView.swift
// Jym
//
// Created by John Smith on 5/9/23.
//
import SwiftUI
class SharedData: ObservableObject {
@Published var presented = true
}
struct WorkoutTabView: View {
@State var workoutsPath = NavigationPath()
@State var emptyPath = NavigationPath()
@State var intPath: [Int] = []
@State var workoutDays = WorkoutDay.sampleData
@State var mainWorkoutDay = WorkoutDay.sampleData[3]
@State private var tabSelection = 1
@State private var tappedTwice: Bool = false
@StateObject var sharedData = SharedData()
var body: some View {
var handler: Binding<Int> { Binding(
get: { self.tabSelection },
set: {
if $0 == self.tabSelection {
// Lands here if user tapped more than once
tappedTwice = true
}
self.tabSelection = $0
}
)}
TabView(selection: handler) {
// TabView() {
WorkoutDaysView(sampleWorkoutDays: $workoutDays, mainWorkoutDay: $mainWorkoutDay, path: $workoutsPath, intPath: $intPath)
.tabItem {
Label("Workouts", systemImage: "dumbbell")
}
.toolbarBackground(Color("royalBlue"), for: .tabBar)
.onChange(of: tappedTwice, perform: { tappedTwice in guard tappedTwice else { return }
withAnimation(.easeOut(duration: 3)) {
sharedData.presented.toggle()
}
workoutsPath = emptyPath
print("toggled")
self.tappedTwice = false
})
.tag(1)
MainChartView(sampleWorkoutDays: $workoutDays)
.tabItem {
Label("Charts", systemImage: "chart.bar.xaxis")
}
.toolbarBackground(Color("royalBlue"), for: .tabBar)
.tag(2)
SettingsView()
.tabItem {
Label("Settings", systemImage: "gearshape")
}
.toolbarBackground(Color("royalBlue"), for: .tabBar)
.tag(3)
}
.navigationViewStyle(StackNavigationViewStyle())
// .onReceive($tabSelection) { newSelection in
// if newSelection == self.tabSelection {
// // Lands here if user tapped more than once
// tappedTwice = true
// }
// self.tabSelection = newSelection
// }
.environmentObject(sharedData)
}
}
struct WorkoutTabView_Previews: PreviewProvider {
static var previews: some View {
WorkoutTabView()
}
}