0

Test setup:

I have a View that displays modally a Map with annotations:

struct Annotation: Identifiable {
    let id = UUID()
    let name: String
    let coordinate: CLLocationCoordinate2D
}

struct MapViewSWUI: View {
    @Binding var show_map_modal: Bool
    @State var region: MKCoordinateRegion
    
    var body: some View {       
        let _ = Self._printChanges()
        VStack {
            ZStack { // Top bar
                Text("Oo")
                    .bold()
                HStack {
                    Button(action: {
                        show_map_modal = false
                    }) {
                        HStack(spacing: 10) { 
                            Image(systemName: "chevron.left")
                            Text(NSLocalizedString("BACK", comment: " "))
                        }
                        .padding(EdgeInsets(top: 0, leading: 10, bottom: 0, trailing: 0))
                    }
                    Spacer()
                }
            }
            let annotations = [Annotation(name: "0", 
                                          coordinate: CLLocationCoordinate2D(latitude: 49.450534, longitude: 8.6694930)),
                               Annotation(name: "1", 
                                          coordinate: CLLocationCoordinate2D(latitude: 49.450701, longitude: 8.6677427))
            ]
            Map(coordinateRegion: $region,
                    interactionModes: .all,
                    showsUserLocation: false,
                    annotationItems: annotations) { annotation in
                MapAnnotation(coordinate: annotation.coordinate, anchorPoint: CGPoint(x: 0.5, y: 1)) {
                    GeometryReader { geo in
                        Color(.green)
                        .onAppear {
                            print("Annotation coordinate: (\(annotation.coordinate.latitude),\(annotation.coordinate.longitude))")
                            print(".global origin: \(geo.frame(in: .global).origin)")
                        }
                    }
                    .frame(width: 30, height: 30)
                }
            }
        } // VStack
    }
}  

When show_map_modal is set to true, the map is shown with the test annotations:

enter image description here

Problem:

When the map is shown the following is normally logged:

MapViewSWUI: @self, @identity, _region, _annotationDragged changed.
2023-01-07 09:19:17.254324+0100 ShopEasy![47736:11270478] Metal API Validation Enabled
MapViewSWUI: _region changed.
Annotation coordinate: (49.450534,8.669493)
.global origin: (271.94092664926427, 438.1697202246186)
Annotation coordinate: (49.450701,8.6677427)
.global origin: (91.00613205620596, 411.6026828329208)  

However it may also happen that the following is logged:

MapViewSWUI: @self, @identity, _region, _annotationDragged changed.
MapViewSWUI: _region changed.
Annotation coordinate: (49.450701,8.6677427)
.global origin: (-15.0, 76.66666666666666)
Annotation coordinate: (49.450534,8.669493)
.global origin: (-15.0, 76.66666666666666)

When I dismiss the modally shown map using the back button ("Zurück"), and display the map again, the same happens (one of the logs above).

Workarounds tried:

  • When, within GeometryReader .onAppear, I embed the print statements in DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { // … }, the .global frame coordinates seem always to be correct. But this seems to be a hack.
  • When I replace .onAppear by .onTapGesture, the .global frame coordinates also seem always to be correct. Unfortunately, I need the coordinates when the annotations appear on the screen, without further user interaction.

Questions:

  • How is it possible that the annotations (green square) are correctly placed on the map, but the GeometryReader gives sometimes the correct .global screen coordinates, but sometimes another strange value (-15.0, 76.66666666666666) that is, if it is given, always the same? Is this a SwiftUI bug?
  • Is something wrong with my code? And if so, how to do it right?
Reinhard Männer
  • 14,022
  • 5
  • 54
  • 116

0 Answers0