0

Setup:

My app uses a SwiftUI Map, essentially as

struct MapViewSWUI: View {
    @Binding private var show_map_modal: Bool
    @State private var region: MKCoordinateRegion
//…
    init(show_map_modal: Binding<Bool>) {
        self._show_map_modal = show_map_modal
        self.region = // Some computed region
//…
    var body: some View {       
//…
        Map(coordinateRegion: $region)
            .frame(width: 400, height: 300) // Some frame for testing
    }
}  

Using this code, I can show the map modally without problems.

Problem:

If I out comment the .frame view modifier, I get the runtime error

Modifying state during view update, this will cause undefined behavior.  

with the following stack frame:
enter image description here

Question:

Why is it in my case required to set a frame for the Map? This tutorial does it, but Apple's docs don't. How to do it right?

PS:

I have read this answer to a similar question and tried to catch the error with a runtime breakpoint, but it does not show anything interesting:
enter image description here

I found an answer to another questions related to the same error, but it doesn't apply here.

EDIT:

Workaround found, but not understood:

My map is presented modally from another view. This view has a state var that controls the presentation:

@State private var show_map_modal = false

The body of the view consists of a HStack with some views, and a fullScreenCover view modifier is applied to the HStack:

var body: some View {
    HStack {
    // …
    }
    .fullScreenCover(isPresented: $show_map_modal) {
        MapViewSWUI(show_map_modal: $show_map_modal, itemToBeDisplayed: viewItem)
            .ignoresSafeArea(edges: [.leading, .trailing])
        }
}  

If the map is presented in this way, no run time error is raised.

However, if I include (as it was done up to now) .top or .bottom in the edge set, the run time error Modifying state during view update is raised.
I would be glad for any hint to the reason.

Reinhard Männer
  • 14,022
  • 5
  • 54
  • 116

1 Answers1

0

My guess is that the error is not related to the frame at all, but to the update of the region once the sheet is presented.

As you can see in my code, I update the region 3 seconds after presenting the seet. Then, the error shows up.

Could the be happening in your code?

struct ContentView: View {
    @State private var show_map_modal = false
    
    var body: some View {
        Button {
            show_map_modal.toggle()
        } label: {
            Text("Show me the map!")
        }
        .sheet(isPresented: $show_map_modal) {
            MapViewSWUI(show_map_modal: $show_map_modal)
        }
    }
}

struct MapViewSWUI: View {
    @Binding private var show_map_modal: Bool
    @State private var region: MKCoordinateRegion

    init(show_map_modal: Binding<Bool>) {
        self._show_map_modal = show_map_modal
        self.region = MKCoordinateRegion(
            center: CLLocationCoordinate2D(
                latitude: 51.507222,
                longitude: -0.1275),
            span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5)
        )
    }

    var body: some View {
        VStack(alignment: .trailing) {
            Button("Done") {
                show_map_modal.toggle()
            }
            .padding(10)
            
            Map(coordinateRegion: $region)
        }
//        .frame(width: 400, height: 300) // Some frame for testing
        .onAppear {
            DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
                self.region = MKCoordinateRegion(
                    center: CLLocationCoordinate2D(
                        latitude: 31.507222,
                        longitude: -1.1275),
                    span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5)
                )
            }
        }
    }
}

enter image description here

Alex Luque
  • 123
  • 2
  • 6
  • Thanks for your test. Actually, it is very hard for me (say, impossible) to read your code or the logs in your video, even if it is zoomed in. My impression is that you assign a 1st region during init, and after it appeared, you assign a 2nd region after 3 sec, and this happens apparently without the error that I described. My question, however, was, why my simple code without `.frame` modifier produces an error, but with modifier it does not. – Reinhard Männer Dec 20 '22 at 16:45
  • I'm sorry. I re recorded the GIF without the code so it could be seen better and added the code to the answer. I hope this time you can see how the error you described shows up in the log. – Alex Luque Dec 20 '22 at 16:59
  • You are surely right that the region update causes the runtime error. This is also indicated by the stack trace that I showed in my question. Apparently, assigning a fixed frame prevents the region update. But shouldn't SwiftUI be responsible for the layout instead of me? I think this is a SwiftUI Map bug. And I still don't know how to set a reasonable frame as a workaround. – Reinhard Männer Dec 21 '22 at 07:26