Search code examples
swiftswiftuimapkitlayoutmargins

MKMapView layoutMargins not updating


I am trying to move center of interests of a MKMapView() with layout margins. It works but only on init then I can change the value or do anything the map wont update the margins.

The MapView :

import SwiftUI
import MapKit

struct MapView: UIViewRepresentable {
    
    @StateObject var manager: StateManager
    @ObservedObject private var locationManager = LocationManager()
    
    var mapView = MKMapView()
    
    func makeUIView(context: Context) -> MKMapView {
        print("NEW MAP VIEW")
        mapView.delegate = context.coordinator
        mapView.isRotateEnabled = true
        mapView.showsUserLocation = true

        // This one works well
        mapView.directionalLayoutMargins = NSDirectionalEdgeInsets(
            top: 0.0,
            leading: 0.0,
            bottom: 100.0,
            trailing: 0.0
        )

        return mapView
    }

    // ...
}

extension MapView {
    func margins( vertical: CGFloat ) -> some View {
        print("margins", mapView.directionalLayoutMargins.bottom, "<->", vertical)
        mapView.directionalLayoutMargins = NSDirectionalEdgeInsets(
            top: 0.0,
            leading: 0.0,
            bottom: vertical,
            trailing: 0.0
        )
        return self
    }

    // ...
}

The print occurs and the value (vertical) is correct but the mapView.directionalLayoutMargins.bottom return 0.0 despite being stuck at 100.0 from the init().

To complete the vision here is the main view:

struct HomeView: View {
    
    @StateObject private var manager: StateManager = StateManager()
    
    @State private var margins: CGFloat = 80.0
    
    var body: some View {
        ZStack(alignment: .leading) {
            MapView(manager: manager)
                .margins(
                    vertical: manager.verticalMargin
                )
                .ignoresSafeArea()
            
            SheetView(manager: manager)
        }
        .ignoresSafeArea()
    }
}

Any idea how to fix this behavior?

Thx!


Solution

  • I found my mistake, I have to use the updateUIView method and its view parameter to update any change in the view.

    func updateUIView(_ view: MKMapView, context: Context) {
        view.directionalLayoutMargins = NSDirectionalEdgeInsets(
            top: 0.0,
            leading: 0.0,
            bottom: newMarginData,
            trailing: 0.0
        )
    }
    

    And now the view did change.