TEAM LICENSES: Save money and learn new skills through a Hacking with Swift+ team license >>

Basic Navigation Stack - working but multiple errors

Forums > SwiftUI

I’m trying to put together a simple text selection app for MacOS. It’s for my own use and is my first attempt at SwiftUI. The SubjectSelectionView will list approx 15 subjects and each subject navigates to a SubjectCommentsView which has 2 tabs, one for the two different types of comment (Observation / Recommendation). All of the comments are contained in the Model file. Text comments that are selected are copied to the clipboard and the view returns back to the SubjectSelectionView.

Very much based on NavStackIntro2 on YouTube - Big thanks to Stewart Lynch.

All is working as I want it to, but I am getting multiple “A navigationDestination for was declared earlier on the stack. Only the destination declared closest to the root view of the stack will be used.” and “List with selection: SelectionManagerBox<Never> tried to update multiple times per frame.” errors.

I can’t work out what is wrong. Can someone help me out please?

  import SwiftUI
@main
struct AppEntry: App {
    @StateObject var router = Router()
    var body: some Scene {
        WindowGroup {
            SubjectSelectionView()
                .environmentObject(router)
        }
    }
}

Router

  import SwiftUI
class Router: ObservableObject {
    @Published var path = NavigationPath()

    func reset() {
        path = NavigationPath()
    }
}

Subject Selection View

  import SwiftUI
struct SubjectSelectionView: View {
    @EnvironmentObject var router: Router

    var body: some View {
        NavigationStack(path: $router.path) {
            List(Subject.sample) { subject in
                NavigationLink(value: subject) {
                    HStack {
                        Text(subject.name)
                    }
                }
            }
            .navigationDestination(for: Subject.self) { subject in
                SubjectCommentsView(vSubject: subject)
            }
            .navigationTitle("Q Subject selection...")
        }
    }
}

Subject Comments View

  import SwiftUI
let pasteBoard = NSPasteboard.general

struct SubjectCommentsView: View {
    @EnvironmentObject var router: Router
    var vSubject: Subject

    var body: some View {
        VStack(alignment: .leading) {
            HStack {
                Text("Q - \(vSubject.name)")
                    .font(.headline)
            }
            TabView {
                VStack{
                    // Observation Comments...(isObservation = True)
                    List(vSubject.comments.filter { $0.isObservation}) { subject in
                        NavigationLink(value: subject) {
                           Text (subject.name)
                        }
                    }
                }
                .tabItem {
                    Text ("Observation Comments...")
                }
                VStack{
                    // Recommendation Comments...(isObservation = False)
                    List(vSubject.comments.filter { !$0.isObservation}) { subject in
                        NavigationLink(value: subject) {
                            Text (subject.name)
                        }
                    }
                }
                .tabItem {
                    Text ("Recommendation Comments...")
                }
            }

            Button("Return to Subjects...") {
              router.reset()
            }
        }
       .padding()
    .navigationTitle("\(vSubject.name) Comments...")
     .navigationDestination(for: Comment.self) { subject in
            SubjectSelectionView()

            // This prints out the correct comment
        .onAppear(perform: {
                    let selectedComment = subject.name as String

            //    Call Copy Function
                    CommentCopy(selectedComment:selectedComment)
                })
        }
    }
}

func CommentCopy(selectedComment: String){
    let _ = print("Copied - \(selectedComment)")

    pasteBoard.clearContents()
    pasteBoard.writeObjects([selectedComment as NSString])
}

Models

  import Foundation
struct Subject: Identifiable, Hashable {
    var name: String
    var comments: [Comment]
    var id: String {name}

    static var sample: [Subject] {
        [
            Subject(name: "Door", comments: Comment.all.filter{$0.subject == "Door"}),
            Subject(name: "Window", comments: Comment.all.filter{$0.subject == "Window"}),
        ]}
}

// All Comments (Both Recommendation and Observation)
struct Comment: Identifiable, Hashable {
    var name: String
    var subject: String
    var isObservation: Bool
    var id: String {name}
    static var all: [Comment] {
        [
            // Observations....
            Comment (name: "Door Comment 4...", subject: "Door", isObservation: true),
            Comment (name: "Window Comment 4...", subject: "Window", isObservation: true),

            // Recommendations...
            Comment (name: "Door Comment 5...", subject: "Door", isObservation: false),
            Comment (name: "Window Comment 5...", subject: "Window", isObservation: false),
        ]
    }

    var matchingSubjects: [Comment] {
        Self.all.filter {$0.subject == subject}
    }
}

   

In case it helps anyone else, I Googled a lot and after a great deal of trial and error found that adding another

 router.reset()

after the call to the CommentCopy function in Subjects Comment View got rid of all the errors.

   

Hacking with Swift is sponsored by String Catalog.

SPONSORED Get accurate app localizations in minutes using AI. Choose your languages & receive translations for 40+ markets!

Localize My App

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.