8.4 C
Canberra
Tuesday, August 19, 2025

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 wish to programmatically swap to the second tab after which instantly push a element display screen 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("Hey from FirstView")
            }
        }
    }
}


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

struct SecondTab: View {
    @ObservedObject var viewModel: SecondTabViewModel
    @State personal 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 personal var selectedTab = 0
    @StateObject personal 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.most important.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 difficulty :

  • The closure is accurately referred to as after I faucet the button in FirstTab.
  • The tab switches to SecondTab.
  • I count on the DetailView to robotically push within the NavigationStack.

However nothing seems – onChange known as, however no push happens.

If I wrap the textToShow inside a DispatchQueue.most important.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.most important.asyncAfter(deadline: .now() + 1) {
        secondVM.textToShow = textual content
    }
}

However this seems like a hack.

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

Is there a really useful, clear approach in SwiftUI to alter tab after which push a vacation spot in that tab’s NavigationStack?

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

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

[td_block_social_counter facebook="tagdiv" twitter="tagdivofficial" youtube="tagdiv" style="style8 td-social-boxed td-social-font-icons" tdc_css="eyJhbGwiOnsibWFyZ2luLWJvdHRvbSI6IjM4IiwiZGlzcGxheSI6IiJ9LCJwb3J0cmFpdCI6eyJtYXJnaW4tYm90dG9tIjoiMzAiLCJkaXNwbGF5IjoiIn0sInBvcnRyYWl0X21heF93aWR0aCI6MTAxOCwicG9ydHJhaXRfbWluX3dpZHRoIjo3Njh9" custom_title="Stay Connected" block_template_id="td_block_template_8" f_header_font_family="712" f_header_font_transform="uppercase" f_header_font_weight="500" f_header_font_size="17" border_color="#dd3333"]
- Advertisement -spot_img

Latest Articles