Зацикленное значение показывает тот же результат для касания
Я импортировал JSON для:
Country.json (образец)
[
{
display_name: "France",
timezone: "placeholder",
longitude: 13.33,
latitude: 15.34
},
{
display_name: "California",
timezone: "EST",
longitude: 33.33,
latitude: 12.34
},
]
У меня есть функция
getAnnotated
который выполняет итерацию по странам, чтобы создать массив
AnnotatedItem
. Это используется в
Map
и зацикливается, чтобы на самом деле создать
MapAnnotation
. Затем передается вспомогательной функции
getCountry
. Я фильтрую через
countries
получить страну, в которой есть то же самое
display_name
поле как
item
.
Желаемое поведение - иметь аннотацию / маркер над каждой страной, и при нажатии на эту аннотацию появится модальный / лист, который дает информацию о стране.
Моя проблема в том, что если я увеличен и на экране есть только одна аннотация / маркер, при нажатии на него отображается правильная страна.
Если я уменьшу масштаб карты и есть несколько аннотаций, все аннотации, которые я нажимаю, будут одинаковыми.
country
информация для каждого. Я предполагаю, что что-то не так с тем, как я зацикливаю.
var countries = Bundle.main.decode("Countries.json")
struct AnnotatedItem: Identifiable {
let id = UUID()
var name: String
var coordinate: CLLocationCoordinate2D
}
struct MapView: View {
@State var showSheet = false
@State private var region = MKCoordinateRegion(
center: CLLocationCoordinate2D(
latitude: 25.7617,
longitude: 80.1918
),
span: MKCoordinateSpan(
latitudeDelta: 10,
longitudeDelta: 10
)
)
func getAnnotated() -> [AnnotatedItem] {
var pointsOfInterest = [AnnotatedItem]()
for i in countries {
pointsOfInterest.append(AnnotatedItem(name: i.display_name, coordinate: .init(latitude: i.latitude, longitude: i.longitude)))
}
return pointsOfInterest
}
func getCountry(newItem: AnnotatedItem) -> Country {
let country = countries.filter{ $0.display_name == newItem.name }
return country[0]
}
var body: some View {
Map(coordinateRegion: $region, annotationItems: getAnnotated()) { item in
MapAnnotation(coordinate: item.coordinate) {
Button(action: {
showSheet.toggle()
}){
Image(systemName: "airplane")
.foregroundColor(.white)
.padding()
}
.background(Circle())
.foregroundColor(Color.green)
.sheet(isPresented: $showSheet) {
SheetView(country: getCountry(newItem: item))
}
}
}
}
}
1 ответ
Я бы попробовал что-то вроде этого, чтобы добиться желаемого поведения:
class SelectedCountry: ObservableObject {
@Published var item: AnnotatedItem = AnnotatedItem(name: "no name", coordinate: CLLocationCoordinate2D())
}
struct MapView: View {
@ObservedObject var selected = SelectedCountry() // <--- here
@State var showSheet = false
...
var body: some View {
Map(coordinateRegion: $region, annotationItems: getAnnotated()) { item in
MapAnnotation(coordinate: item.coordinate) {
Button(action: {
selected.item = item // <--- here
showSheet.toggle()
}){
Image(systemName: "airplane")
.foregroundColor(.white)
.padding()
}
.background(Circle())
.foregroundColor(Color.green)
}
}
// ---> put the sheet here
.sheet(isPresented: $showSheet) {
SheetView(country: getCountry(newItem: selected.item))
}
}