swiftswiftuimapkitmapkitannotation

How would I make my map annotation open the correct view? - Swift


I am trying to make it so that every time I click on my map annotation the corresponding view will come up but it doesn't seem to be the case. It looks like it's all mixed around and sometimes having the same view show up multiple times. This is the code I have so far:

 Map(coordinateRegion: $region, interactionModes: .all, showsUserLocation: true, userTrackingMode: nil, annotationItems: sclocations) { item in
                    MapAnnotation(coordinate: item.location) {
                        Button(action: {
                            self.activeSheet = .sheetA
                        }, label: {
                            Image(systemName: "mappin")
                                .foregroundColor(.red)
                        }) //: BUTTON
                        .sheet(item: $activeSheet) { sheet in
                            switch sheet {
                                case .sheetA:
                            SCDetailView(sclocations: item)
                            }
                        }
                    }
                }

Solution

  • I'm going to have to make some assumptions here, since you aren't showing what the type of item is. Let's say it's called LocationItem. The important thing is that it conforms to Identifiable:

    struct LocationItem : Identifiable {
        var id = UUID()
        var name : String
        var location: CLLocationCoordinate2D
    }
    

    You'd need a @State variable to store an optional LocationItem on your view:

    @State var locationItem : LocationItem?
    

    Your button would set the locationItem:

    Button(action: {
       self.locationItem = item
    })
    

    And your sheet call would look like this:

    .sheet(item: $locationItem) { locationItem in
       SCDetailView(sclocations: locationItem) //note how I'm using locationItem here -- the parameter from the closure                          
    }
    

    Finally, I'd move that sheet so that it is outside your MapAnnotation so your entire view body would look more like:

    Map(coordinateRegion: $region, interactionModes: .all, showsUserLocation: true, userTrackingMode: nil, annotationItems: sclocations) { item in
                        MapAnnotation(coordinate: item.location) {
                            Button(action: {
                                self.locationItem = item
                            }) {
                               Image(systemName: "mappin").foregroundColor(.red)
                            }
                        }
                    }
    .sheet(item: $locationItem) { locationItem in
       SCDetailView(sclocations: locationItem)                    
    }
    

    Keep in mind that since you didn't give a complete code sample, like I said, I'm guessing about some things, so you may have to extrapolate this into your own solution (like making your type into Identifiable).