Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI Map causes "modifying state during view update"

I'd like to implement a basic Map view that will center on the users location when they tap a button, similar to the Apple Maps app. I tried the following, but whenever I tap the button, [SwiftUI] Modifying state during view update, this will cause undefined behavior. is printed in the console. It seems to me that updating the tracking state variable is causing the error. However, I'm not sure how else the state variable is meant to be used. The app does behave as intended despite printing the error. Does anyone have any experience with this or know what might be wrong?

struct ContentView: View {
    @State var region: MKCoordinateRegion = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 47.3769, longitude: 8.5417), latitudinalMeters: 2000, longitudinalMeters: 2000)
    @State var tracking = MapUserTrackingMode.follow
    
    var body: some View {
        ZStack {
            Map(coordinateRegion: $region, interactionModes: .all, showsUserLocation: true, userTrackingMode: $tracking)
                .ignoresSafeArea()
                .task {
                    let locationManager = CLLocationManager()
                    locationManager.requestWhenInUseAuthorization();
                }
            Button {
                tracking = .follow
            } label: {
                Image(systemName: tracking == .follow ? "location.fill" : "location")
                    .padding()
            }
            .background(.white)
        }
    }
}
like image 309
Carl Avatar asked May 09 '26 18:05

Carl


1 Answers

I started to have a similar issue when moving to iOS 16 (Xcode 14.1). In my case I had the following:

// LocationView

struct LocationView : View {

    @StateObject private var viewModel : ViewModel

    var body: some View {

        Map(coordinateRegion: $viewModel.region)
            .clipShape(RoundedRectangle(cornerRadius: 10))
    }
}


// View Model

@MainActor final class ViewModel : ObservableObject {

    ...

    @Published var region : MKCoordinateRegion

    ...
}

What I did in this case to remove the warning was to create a Binding in my View to the Published property in the viewModel:

private var region : Binding<MKCoordinateRegion> {
        
    Binding {
            
        viewModel.region
            
    } set: { region in
            
        DispatchQueue.main.async {
            viewModel.region = region
        }
    }
} 

And then change the view to use this binding instead of the published variable in the viewModel:

    Map(coordinateRegion: region)

The application keeps working as expected and the error/warning is no longer showing up.

like image 128
fcollf Avatar answered May 12 '26 21:05

fcollf



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!