Search code examples
swiftuimapkitwatchkitapple-watch

Apple Watch SwiftUI Map events? How do I read the current region span on digital crown rotation?


I have a zoom enabled map on my Apple Watch SwiftUI app and I'd like to save the current zoom level or region span when the user rotates the digital crown to zoom in or out in order to prevent the zoom to change when new user positions arrives. Is that even possible? How can I use onChange to read the Map.region.span property?


Solution

  • This is the view I use in a watchOS app. As you can see, the initializer for the map allows you to use all of these different parameters. Because this view was called from a different view that provided the information, I used Bindings for the parameters, but if the view was self contained, I could have just as easily used State, etc. Of course, anything that changes on the map, is reflected out in these variables. One of those variables I am passing in is the region. As that is changed graphically on the map, it is also changed in the variable.

    struct WatchMapView: View {
        
        @EnvironmentObject var location: GeoLocation
        
        @ObservedObject var updater = Updater.shared
    
        @Binding var region: MKCoordinateRegion
        let userTrackingMode: MapUserTrackingMode = .none
        @Binding var currentPlace: Place
        @Binding var places: [Place]
    
        var body: some View {
            ZStack {
                Map(
                    coordinateRegion: $region,
                    interactionModes: MapInteractionModes.all,
                    showsUserLocation: false,
                    userTrackingMode: $userTrackingMode,
                    annotationItems: places) { place in
                    MapMarker(coordinate: place.coordinate, tint: .red)
                }
            }
        }
    }