简体   繁体   中英

Why is SwiftUI Map modifying the state of its calling struct, if no frame is assigned?

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:
在此处输入图像描述

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:
在此处输入图像描述

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.

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)
                )
            }
        }
    }
}

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM