UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

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

   

Hacking with Swift is sponsored by RevenueCat.

SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure your entire paywall view without any code changes or app updates.

Click to save your free spot now

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.