ios – Switching tab and pushing to NavigationStack doesn’t present new View

0
1
ios – Switching tab and pushing to NavigationStack doesn’t present new View


I’ve a TabView with two tabs (FirstTab and SecondTab).

From the primary tab, I need to programmatically swap to the second tab after which instantly push a element display contained in the second tab’s NavigationStack.

I wrote a simplified instance:

struct FirstTab: View {
    var onNavigate: (String) -> Void

    var physique: some View {
        VStack {
            Textual content("FirstTab")

            Button("Go to SecondTab") {
                onNavigate("Whats up from FirstView")
            }
        }
    }
}


class SecondTabViewModel: ObservableObject {
    @Printed var textToShow: String? = nil
}

struct SecondTab: View {
    @ObservedObject var viewModel: SecondTabViewModel
    @State non-public var path = NavigationPath()

    var physique: some View {
        NavigationStack(path: $path) {
            VStack {
                Textual content("SecondTab")
            }
            .navigationDestination(for: String.self) { worth in
                DetailView(textual content: worth)
            }
            .onChange(of: viewModel.textToShow) { oldValue, newValue in
                print("onChange SecondTab textual content: (String(describing: newValue))")
                if let newValue = newValue, newValue != oldValue {
                    print("Pushing DetailView with: (newValue)")
                    path.append(newValue)
                }
            }
        }
    }
}

struct DetailView: View {
    let textual content: String

    var physique: some View {
        VStack {
            Textual content("DetailView")

            Textual content("Textual content: (textual content)")
        }
    }
}

struct ContentView: View {
    @State non-public var selectedTab = 0
    @StateObject non-public var secondVM = SecondTabViewModel()

    var physique: some View {
        TabView(choice: $selectedTab) {
            FirstTab { textual content in
                print("Closure referred to as with textual content: (textual content)")
                selectedTab = 1 // swap tab
                DispatchQueue.foremost.asyncAfter(deadline: .now() + 1) {
                    secondVM.textToShow = textual content
                }
            }
            .tabItem { Label("First", systemImage: "1.circle") }
            .tag(0)

            SecondTab(viewModel: secondVM)
                .tabItem { Label("Second", systemImage: "2.circle") }
                .tag(1)
        }
    }
}

The problem :

  • The closure is appropriately referred to as once I faucet the button in FirstTab.
  • The tab switches to SecondTab.
  • I anticipate the DetailView to mechanically push within the NavigationStack.

However nothing seems – onChange is named, however no push happens.

If I wrap the textToShow inside a DispatchQueue.foremost.asyncAfter (e.g. 0.1 seconds), it really works.

Instance of the workaround:

FirstTab { textual content in
    print("Closure referred to as with textual content: (textual content)")
    selectedTab = 1 // swap tab
    DispatchQueue.foremost.asyncAfter(deadline: .now() + 1) {
        secondVM.textToShow = textual content
    }
}

However this looks like a hack.

Why doesn’t the navigation push (path.append) work when switching tabs instantly?

Is there a beneficial, clear manner in SwiftUI to vary tab after which push a vacation spot in that tab’s NavigationStack?

Ought to I be utilizing a distinct navigation method (e.g. Coordinator, Observable shared state)?

LEAVE A REPLY

Please enter your comment!
Please enter your name here