I need to pass some bindings to a sheet that can be written to. What I've come up with works but seems a really inefficient way of doing it.
I have recreated a very simplified version of my code to use as an example.
I have a custom LocationStruct...
struct LocationStruct {
var id = UUID()
var name: String
var location: CLLocationCoordinate2D?
var haveVisited = false
}
I then have the parent view that displays a number of the LocationStruct's - the origin, an array of waypoints and the destination...
struct ContentView: View {
@State var origin = LocationStruct(name: "Paris")
@State var waypoints = [LocationStruct(name: "Berlin"), LocationStruct(name: "Milan")]
@State var destination = LocationStruct(name: "Venice")
@State var selectedLocation: Int?
@State var showSheet = false
var body: some View {
VStack{
HStack{
Text("Origin:")
Spacer()
Text(origin.name)
}
.onTapGesture{
selectedLocation = 1000
showSheet = true
}
ForEach(waypoints.indices, id:\.self){ i in
HStack{
Text("Waypoint \(i + 1):")
Spacer()
Text(waypoints[i].name)
}
.onTapGesture{
selectedLocation = i
showSheet = true
}
}
HStack{
Text("Destination:")
Spacer()
Text(destination.name)
}
.onTapGesture{
selectedLocation = 2000
showSheet = true
}
}
.padding()
.sheet(isPresented: $showSheet){
LocationSheet(origin: $origin, waypoints: $waypoints, destination: $destination, selectedLocation: $selectedLocation)
}
}
}
I then need to read and write to the location object that was tapped on the ContentView. I'm setting selectedLocation value to 1000 or 2000 for origin and destination otherwise its set to the waypoint array index (waypoints are limited in number so will not reach 1000).
I'm having to repeating "if let selectedLocation = ..." in quite a few places. Is there a better way of doing this, maybe some sort of computed binding or something?
struct LocationSheet: View {
@Binding var origin: LocationStruct
@Binding var waypoints: [LocationStruct]
@Binding var destination: LocationStruct
@Binding var selectedLocation: Int?
var body: some View {
VStack{
if let selectedLocation = selectedLocation {
switch selectedLocation {
case 1000:
TextField("", text: $origin.name).textFieldStyle(.roundedBorder)
case 2000:
TextField("", text: $destination.name).textFieldStyle(.roundedBorder)
default:
TextField("", text: $waypoints[selectedLocation].name).textFieldStyle(.roundedBorder)
}
}
Button(action: { markAsVisted() }){
Text("Visited")
}
}
.padding()
}
func markAsVisted(){
if let selectedLocation = selectedLocation {
switch selectedLocation {
case 1000:
origin.haveVisited = true
case 2000:
destination.haveVisited = true
default:
waypoints[selectedLocation].haveVisited = true
}
}
}
}
Thanks in advance
