Home > Software design >  In Swift how do I programmatically select a navigation link in a list
In Swift how do I programmatically select a navigation link in a list

Time:11-08

In a Swift navigation split view once all of the data has been loaded from core data (indicated by the isLoading variable being equal to false) the Progress View stops being displayed but the detail view is now empty. What I would like have happen at this point is for the Summary view to be displayed. I think this would require programmatically setting the list selection to "Home". How do I need to modify my code to accomplish this? Below is the code.

struct ContentView: View {
    @State private var selection: String?
    @ObservedObject private var vooVM: VOOViewModel
    @ObservedObject private var vfiaxVM: VFIAXViewModel
    @ObservedObject private var prinVM: PrincipalViewModel
    init(vooVM: VOOViewModel, vfiaxVM: VFIAXViewModel, prinVM: PrincipalViewModel) {
        self.vooVM = vooVM
        self.vfiaxVM = vfiaxVM
        self.prinVM = prinVM
    }
    let myList = ["Home", "VOO Chart", "VOO List", "VFIAX Chart", "VFIAX List", "Principal Chart", "Principal List"]
    var body: some View {
        NavigationSplitView {
            List(myList, id: \.self, selection: $selection) { listItem in
                NavigationLink(value: listItem) {
                    Text(listItem)
                } // end navigation link
            } // end list
            .navigationSplitViewColumnWidth(250)
        } detail: {
            if vooVM.isloading == true || vfiaxVM.isloading == true || prinVM.isloading == true {
                Spacer()
                ProgressView()
                    .navigationSplitViewColumnWidth(950)
                Spacer()
            } else if selection == "Home" {
                Summary(vooVM: vooVM, vfiaxVM: vfiaxVM, prinVM: prinVM)
                    .navigationSplitViewColumnWidth(950)
            } else if selection == "VOO Chart" {
                LineChart(passedInArray: vooVM.values1)
                    .navigationSplitViewColumnWidth(950)
            } else {
                Text("Select an option in the list")
            }
            Spacer()
        }
        .frame(width: 1200,height: 900, alignment: .center)
    } // end body
} // end struct


CodePudding user response:

After further reviewing my code including the if... else if... logic I realized that I only need to change one line in the code. If I set the selection to "Home" initially, once all of the isLoading variables are false the if... else if... logic will find selection = "Home" and in turn the Summary View will be shown automatically.

change: @State private var selection: String?
to:     @State private var selection: String = "Home"

CodePudding user response:

Workingdog is correct. I had not really solved the problem. I have updated the code to include two onChange events that were added to the Navigation Link and the list now works programmaticaly.

@State private var selection: String?

.onChange(of: prinVM.isloading  && vooVM.isloading && vfiaxVM.isloading) { newValue in
    self.selection = "Home"
} // end on change
.onChange(of: selection) { [selection] newValue in
    if (selection == "Home" && newValue == "VOO Index Fund") {
        self.selection = "VOO Chart"
    } else if (selection == "VOO Chart" && newValue == "VOO Index Fund") {
        self.selection = "Home"
    } else if (selection == "VOO List" && newValue == "VFIAX Index Fund") {
        self.selection = "VFIAX Chart"
    } else if (selection == "VFIAX Chart" && newValue == "VFIAX Index Fund") {
        self.selection = "VOO List"
    } else if (selection == "VFIAX List" && newValue == "Principal Index Fund") {
        self.selection = "Principal Chart"
    } else if (selection == "Principal Chart" && newValue == "Principal Index Fund" ) {
         self.selection = "VFIAX List"
    } else {
   }
} // end on change
  • Related