0

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()
    }
}

Emet Amil
  • 1
  • 1

1 Answers1

0

I found out that if I use NavigationTitle, the issue goes away. I wasn't using NavigationTitle before and just making my own custom title on top.

Emet Amil
  • 1
  • 1