Search code examples
iosswiftdictionaryswiftuiannotations

When SwiftUI View is set to the content of MapAnnotation, the frame does not update properly when View is changed


In the body, I implemented each View in the if else syntax . Every time I click the button to toggle the boolean value and check the UI, it works perfectly as I think.

struct ContentView: View {
    
    @State private var isSelected: Bool = false
    var body: some View {
        VStack {
            if isSelected {
                Text("isSelected" )
                    .font(.title)
                    .foregroundStyle(.blue)
                    .background(.green)
            } else {
                Text("isNotSelected")
                    .font(.callout)
                    .foregroundStyle(.blue)
                    .background(.red)
            }
            
            Button("Change select state") {
                isSelected.toggle()
            }
        }
    }
}

enter image description here

However, the UI looks strange when the same view is just in MapAnnotation. As before, after clicking on the button to toggle the boolean value and check the UI, the Text is truncated.

struct Place: Identifiable {
    let id = UUID()
    let latitude: Double
    let longitude: Double
}

struct ContentView: View {
    
    @State private var isSelected: Bool = false
    @State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 37.566535,
                                                                          longitude: 126.9779692),
                                           span: MKCoordinateSpan(latitudeDelta: 0.5,
                                                                  longitudeDelta: 0.5))

    let places: [Place] = [
        Place(latitude: 37.566535,
              longitude: 126.9779692),
        Place(latitude:35.1795543,
              longitude: 129.0756416)
    ]
    
    var body: some View {
        VStack {
            Map(coordinateRegion: $region,
                annotationItems: places) { place in
                
                // 🙌🏻🙌🏻🙌🏻🙌🏻 used as MapAnnotation content
                MapAnnotation(coordinate: CLLocationCoordinate2D(latitude: place.latitude,
                                                                 longitude: place.longitude)) {
                    if isSelected {
                        Text("isSelected" )
                            .font(.title)
                            .foregroundStyle(.blue)
                            .background(.green)
                    } else {
                        Text("isNotSelected")
                            .font(.callout)
                            .foregroundStyle(.blue)
                            .background(.red)
                    }
                } // MapAnnotation
            }
            
            Button("Change select state") {
                isSelected.toggle()
            }
        }
    }
}

enter image description here

Even if I don't use the if else syntax to seperate the View, and use a single Text View setting value with the ternary operator, the UI looks weird as before.

MapAnnotation(coordinate: CLLocationCoordinate2D(latitude: place.latitude,
                                                 longitude: place.longitude)) {
    Text(isSelected ? "isSelected" : "isNotSelected")
        .font(isSelected ? .title : .callout)
        .foregroundStyle(.blue)
        .background(isSelected ? .green : .red)
}

And when I scroll the map, the UI is updated as I expected.

enter image description here

Is this a SwiftUI bug? Or am I missing something?


Solution

  • Give it fixed size, for example

    MapAnnotation(coordinate: CLLocationCoordinate2D(latitude: place.latitude, longitude: place.longitude)) {
        VStack {
            if isSelected {
                Text("isSelected" )
                    .font(.title)
                    .foregroundStyle(.blue)
                    .background(.green)
            } else {
                Text("isNotSelected")
                    .font(.callout)
                    .foregroundStyle(.blue)
                    .background(.red)
            }
        }
        .fixedSize()     // << here !!
    } // MapAnnotation
    

    Actually we don't know internal Map expectation for annotations size, so I cannot say it is a bug.