Зацикленное значение показывает тот же результат для касания

Я импортировал 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))
        }
    }
Другие вопросы по тегам