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

SOLVED: NavigationSplitView Issue

Forums > SwiftUI

Happy New Year everyone,

I am trying to convert one of my apps from NavigationStack to NavigationSplitView. I am having some trouble and I am sure I'm missing something, just not sure what. The below code is what I am using. The Progam is a core data entity, lets say for testing purposes, its like this:

struct Program: : Identifiable, Hashable {
    var id = UUID()
    var name: String
    var date: String
}

When I use the following show the split view, I am able to select the first program and the detail will show up in the detail section, however, when I select a different program the detail isn't changing. As you can see I put some print statements in and can see those get printed out when I select a different program, yet the detail isn't changing.

I am not sure what I'm missing, any help would be appreciated.

struct ListOfProgramsView: View {
    // MARK: - Environment
    @EnvironmentObject var dataManager: DataManager

    // MARK: - State
    @State private var selectedProgram: Program.ID?
    @State private var currentSelectedProgram: Program?

    var body: some View {
        NavigationSplitView {
            List(dataManager.programs, selection: $selectedProgram) { program in
                ProgramsRowView(program: program)
                    .tag(program)
            }
            .navigationTitle(.nbProgramsViewTitle)
            .onChange(of: selectedProgram) { newProgramSelection in
                if let selection = newProgramSelection, let program = dataManager.programs.first(where: { $0.id == selection }) {
                    currentSelectedProgram = program
                    print("Changed Again: \(program.date.dateText(style: .medium))")
                }
            }
        } detail: {
            if let program = currentSelectedProgram {
                ModifyExistingProgramView(program: program, dataManager: dataManager)
                let _ = print("Program Date: \(program.date.dateText(style: .medium))")
            } else {
                NoProgramsView()
            }
        }
        .navigationSplitViewStyle(.balanced)
    }
}

Thanks, Taz

1      

Watched it, I already sent him a Ko-Fi....... The video was helpful and thats how I got as far as I have. However, I think I missing something and I just dont see it right now. So If you have any suggestions on how to change the code I would love to hear them.

Thanks

1      

I didn't make too many changes. Mostly to add fake CoreData. When I select a Program from the list of Programs, the detail side updates.

// Run in Playgrounds to test assumptions, theories.
import SwiftUI
import PlaygroundSupport

struct Program: Identifiable, Hashable {
    var id =     UUID()
    var name:    String
    var date:    String
    var teacher: String

    static var examples = [
        Program(name: "Spells & Charms",  date: "1/1/2012 CE",      teacher: "Flitwick" ),
        Program(name: "Potions",          date: "2/29/1090",        teacher: "Slughorn" ),
        Program(name: "Divination",       date: "9/32/1066",        teacher: "Trelawney"),
        Program(name: "Sorcery",          date: "1/1/1666",         teacher: "Snape"    ),
        Program(name: "Arithmancy",       date: "Solstice 122 BCE", teacher: "Vector"   ),
        Program(name: "Famous Wizards",   date: "1/1/1000",         teacher: "Babbling" )
    ]
}

struct ListOfProgramsView: View {
    let allPrograms = Program.examples
    @State private var selectedProgram:        Program.ID?
    @State private var currentSelectedProgram: Program?

    var body: some View {
        NavigationSplitView {
            List(allPrograms, selection: $selectedProgram) { aProgram in
                Text("\(aProgram.name)").font(.title3)
            }
            .navigationTitle("Divine Programs")
            .onChange(of: selectedProgram) { newProgramSelection in
                if let selection = newProgramSelection, let program = allPrograms.first(where: { $0.id == selection }) {
                    currentSelectedProgram = program
                    print("You selected: \(program.name)")
                }
            }
        } detail: {
            if let program = currentSelectedProgram {
                ProgramsDetailView(program: program)
            } else {
                Text("select a program").font(.largeTitle).foregroundColor(.red)
            }
        }
        .navigationSplitViewStyle(.balanced)
    }
}

struct ProgramsDetailView: View {
    var program: Program
    var body: some View {
        VStack (spacing: 12) {
            Text("\(program.name)").font(.title)
            Text("by \(program.teacher)").font(.body)
            Text("First program: \(program.date)").font(.caption2)
        }
    }
}

PlaygroundPage.current.setLiveView(ListOfProgramsView() )  // <- This allows you to experiment with views in Playgrounds

1      

Ok,

Well, then I'm at a loss. From what I can see mine should be updating the detail, but its not. I'll have to look into it further. I was just not sure if the code I had was/should be working. From what you're telling me it is.

Thanks for your help @Obelix. I appreciate the time you took to look into it.

Taz

1      

TAKE YOUR SKILLS TO THE NEXT LEVEL If you like Hacking with Swift, you'll love Hacking with Swift+ – it's my premium service where you can learn advanced Swift and SwiftUI, functional programming, algorithms, and more. Plus it comes with stacks of benefits, including monthly live streams, downloadable projects, a 20% discount on all books, and free gifts!

Find out more

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

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

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.