I set 3 markers (0, 1, 2) in a map (which is on my ContentView). Now I want to remove only the marker 0 (not 1 and not 2).
All I found was "removeAnnotation", although my marker is just a marker, not declared as an annotation. Nevertheless, I took an answer from stack overflow (https://stackoverflow.com/questions/47959193/swift-4-to-remove-only-one-annotation-not-all/47965214, but it doesn't work.
I am rather a beginner in Swift, so the problem seems (beside the removeAnnotation-Question) to be in my code itself.
My code:
import SwiftUI
import MapKit
struct MyLocationsArray: Identifiable {
let id = UUID()
let number: Int
let name: String
let label: String
let coordinates: CLLocationCoordinate2D
}
struct ContentView: View {
@State var myLocs = [
MyLocationsArray(number: 0, name: "name A", label: "label A", coordinates: CLLocationCoordinate2D(latitude: 39.873563, longitude: 3.170857999999953)),
MyLocationsArray(number: 1, name: "name B", label: "label B", coordinates: CLLocationCoordinate2D(latitude: 39.654235, longitude: 2.947624)),
MyLocationsArray(number: 2, name: "name C", label: "label C", coordinates: CLLocationCoordinate2D(latitude: 39.530, longitude: 2.90))
]
var body: some View {
Map()
{
Marker(myLocs[0].name, coordinate: myLocs[0].coordinates)
Marker(myLocs[1].name, coordinate: myLocs[1].coordinates)
Marker(myLocs[2].name, coordinate: myLocs[2].coordinates)
}
Button("Button title") {
removeSpecificAnnotation()
}
}
func removeSpecificAnnotation() {
for n in myLocs {
if let name = n.name, name == "name A" { // "Conditioner for conditional binding must have Optional type, not 'String'": But my "name" ist a String.
removeAnnotation(n) // "Cannot find removeAnnotation in Scope": But with whatelse can I remove a Marker?
}
}
}
}
I searched through stackoverflow and found an answer, but somehow it doesn't work for my code. In the internet, I didn't find an answer to "how to remove a marker" except to change the pin color to transparent. Ans, as I said, it could also be my general code, as I am a beginner.
In SwiftUI you work with the data
, to achieve what you want. In your case, you don't remove the Marker
, you remove the data that represents it.
So try this approach using the data
( myLocs) to select then remove the selected
MyLocation
, as shown in the example code.
Select/tap a marker on the map, then press the Remove selected
button to remove it from the map
struct MyLocation: Identifiable, Hashable {
let id = UUID()
var number: Int
var name: String
var label: String
var coordinates: CLLocationCoordinate2D
}
struct ContentView: View {
@State private var myLocs = [
MyLocation(number: 0, name: "name A", label: "label A", coordinates: CLLocationCoordinate2D(latitude: 39.873563, longitude: 3.170857999999953)),
MyLocation(number: 1, name: "name B", label: "label B", coordinates: CLLocationCoordinate2D(latitude: 39.654235, longitude: 2.947624)),
MyLocation(number: 2, name: "name C", label: "label C", coordinates: CLLocationCoordinate2D(latitude: 39.530, longitude: 2.90))
]
@State private var selection: MyLocation?
var body: some View {
Map(selection: $selection) {
ForEach(myLocs) { loc in
Marker(loc.name, coordinate: loc.coordinates).tag(loc)
}
}
Button("Remove selected") {
removeSelectedMarker()
}
}
func removeSelectedMarker() {
if let index = myLocs.firstIndex(where: {$0.id == selection?.id}){
myLocs.remove(at: index)
}
}
}
// required for MyLocation Hashable
extension CLLocationCoordinate2D: Equatable, Hashable {
public static func == (lhs: CLLocationCoordinate2D, rhs: CLLocationCoordinate2D) -> Bool {
return lhs.latitude == rhs.latitude && lhs.longitude == rhs.longitude
}
public func hash(into hasher: inout Hasher) {
hasher.combine(latitude)
hasher.combine(longitude)
}
}