Navigation stack yellow warning triangle
Asked Answered
C

4

8

I'm attempting to listen for a change in a boolean value & changing the view once it has been heard which it does successfully, however, results in a yellow triangle. I haven't managed to pinpoint the issue but it doesn't seem to have anything to do with the view that it's transitioning to as even when changed the error still persists.

My code is below

import SwiftUI

struct ConversationsView: View {
    @State var isShowingNewMessageView = false
    @State var showChat = false
    @State var root = [Root]()
    var body: some View {
        NavigationStack(path: $root) {
            ZStack(alignment: .bottomTrailing) {
                ScrollView {
                    LazyVStack {
                        ForEach(0 ..< 20) { _ in
                            Text("Test")
                        }
                    }
                }.padding()
            }

            Button {
                self.isShowingNewMessageView.toggle()
            } label: {
                Image(systemName: "plus.message.fill")
                    .resizable()
                    .renderingMode(.template)
                    .frame(width: 48, height: 48)
                    .padding()
                    .foregroundColor(Color.blue)
                    .sheet(isPresented: $isShowingNewMessageView, content: {
                        NewMessageView(show: $isShowingNewMessageView, startChat: $showChat)
                    })
            }
        }
        .onChange(of: showChat) { newValue in
            guard newValue else { return }
            root.append(.profile)
        }.navigationDestination(for: Root.self) { navigation in
            switch navigation {
            case .profile:
                ChatView()
            }
        }
    }

    enum Root {
        case profile
    }
}

ChatView() Code:

import SwiftUI

struct ChatView: View {
    @State var messageText: String = ""
    var body: some View {
        VStack {
            ScrollView {
                VStack(alignment: .leading, spacing: 12) {
                    ForEach(MOCK_MESSAGES) { message in
                        MessageView(message: message)
                    }
                }
            }.padding(.top)

            MessageInputView(messageText: $messageText)
                .padding()
        }
    }
}

Any support is much appreciated.

Crochet answered 22/11, 2022 at 23:53 Comment(5)
What does the issue say?Meara
@MrDeveloper There's no issue it is literally just switches the view to a yellow warning triangle.Crochet
Well, the problem must be in your "ChatView()" - please provide the code for that view.Heger
@Heger edited with code !Crochet
I very much believe that problem is with navigationDestination modifier place, it should be inside NavigationStack. NavigationStack` always shows when it can't find suitable View for path. Please, check my answerFeldt
F
21

You should use navigationDestination modifier inside your NavigationStack component, just move it.

NavigationStack(path: $root) {
    ZStack(alignment: .bottomTrailing) {
        
        ScrollView {
            LazyVStack {
                ForEach(0..<20) { _ in
                    Text("Test")
                }
            }
        }.padding()
    }.navigationDestination(for: Root.self) { navigation in
        switch navigation {
        case .profile:
            ChatView()
        }
    }

  //...
}

Basically this yellow triangle means NavigationStack can't find suitable component for path. And when you using navigationDestination directly on NavigationStack View or somewhere outside it is ignored

Feldt answered 26/11, 2022 at 11:45 Comment(1)
It seems to work when the navigationDestination is attached directly on NavigationStack inside NavigationSplitView's detail closure (on iPadOS).Norvell
B
1

You must set .environmentObject(root) to NavigationStack in order to provide the NavigationPath to the view subhierarchy (ChatView in your case). Also you must have a @EnvironmentObject property of type Root in your ChatView so that it can read the path.

Bookplate answered 24/11, 2022 at 13:30 Comment(2)
Thanks for the reply - I get the error: Instance method 'environmentObject' requires that '[ConversationsView.Root]' conform to 'ObservableObject'Crochet
you could try having a class that conforms to ObservableObject and that holds a NavigationPath instead of an enum. The response from Evgeny is also correct, you should not use .navigationDestination directly on the NavigationStack, but inside it.Bookplate
T
0

Do not use NavigationDestination directly in NavigationStack. You need to inject it into the first View object in the NavigationStack. The code block is below as an example.

struct BaseTabView: View {

@State private var path = NavigationPath()
@State private var selection = 1

var body: some View {
    NavigationStack(path: $path) {
        TabView(selection: $selection) {
            HomeView()
                .tabItem {
                    Label("Home", systemImage: "house")
                }
                .tag(1)
            
            HistoryView()
                .tabItem {
                    Label("History", systemImage: "clock.arrow.circlepath")
                }
                .tag(2)
        }
        .tint(.red)
        .toolbar {
            ToolbarItem(placement: .topBarTrailing) {
                HStack {
                    Button("", systemImage: "star.square.on.square.fill") {
                        path.append(HomeNavigation.paywall)
                    }
                    .tint(Color.brandColor)
                    Button("", systemImage: "gearshape.fill") {
                        path.append(HomeNavigation.settings)
                    }
                    .tint(Color.brandColor)
                }
            }
        }
        .navigationTitle(TabItem(rawValue: selection)?.navigationTitle ?? "")
        .navigationDestination(for: HomeNavigation.self) { navigation in
            switch navigation {
            case .paywall:
                SettingsView()
            case .settings:
                SettingsView()
            }
        }
    }
}
Tollgate answered 6/3, 2024 at 19:32 Comment(0)
V
0

For any this may help. For me, I kept seeing this because I was navigating to a view that also had a NavigationStack within it. So I guess the nested navigationStack didn't work that well so I simply removed the navigation stack from the second view.

Volume answered 13/6, 2024 at 13:48 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.