The SwiftUI Navigation structures work in ways that are not intuitive to me. For example, I am trying to display a set of data that represents rankings contained in a balloting system that I have created. The ballots all have candidates that are ranked from highest preference to lowest.
Normally, I try to work backwards in SwiftUI, so I built the ballot editor to take a binding to the ballot itself:
struct BallotEditor: View {
@Binding var ballot: Election.Ballot
var maxRank: Int
var body: some View {
VStack {
ForEach($ballot.rankings) { $ranking in
CandidateRankingPicker(maxRanking: maxRank, ranking: $ranking)
}
}
}
}
This is embedded into a view with a list of ballots:
struct BallotsView: View {
@Binding var document: ElectionDocument
var body: some View {
List($document.ballots) { $ballot in
NavigationLink {
BallotEditor(ballot: $ballot, maxRank: document.election.candidates.count)
.padding()
} label: {
BallotListElementView(ballot: ballot)
}
}
}
}
This portion works in the editor. When the ballot is selected, the editor populates the selected candidate choices, and the editing works.
However, when I attempt to insert BallotsView into a TabView, the NavigationLink stops working as expected. I didn't think NavigationLink was the proper way to do this, but it had been working.
TabView {
Tab("Ballots", systemImage: "menucard") {
BallotsView(document: $document)
}
Tab {
CandidateView()
} label: {
Text("Candidates")
}
.tabViewStyle(.sidebarAdaptable)
}
This is my third iteration. I have tried using a List with selection, but in that case, I am unable to pass the binding to the detail view. I just don't understand how this works, and I am preparing a version in Cocoa so that I don't have to deal with it anymore.