Implementing Map Span in iOS 17

I have a map (iOS 17) that displays the three Apple maps types (standard, hybrid, and imagery). When the hybrid or imagery map is displayed for the first time it is zoomed in to the max and out-of-focus. It appears to be a problem with the span. I would like to set the span to fix this, but I'm not sure if span has a new name or is no longer used.

In previous versions of iOS I had a region that defined the span and coordinate center, It appears that this has now been deprecated:

let span = MKCoordinateSpan(latitudeDelta: 0.005, longitudeDelta: 0.005)
let region = MKCoordinateRegion(center: coordinate, span: span)
MapView(region: region, mapType: mapType, coordinate: coordinate)

Here is my actual code for display a map (iOS 17):

struct DetailView: View {

    var item: TravelEntries // <-- coordinates arrive from CoreData Transaction
    @Binding var mapType: Int

    var coordinate: CLLocationCoordinate2D {
        CLLocationCoordinate2D(
            latitude: item.entryLat,
            longitude: item.entryLong)
    }

    var selectedMapStyle: MapStyle {
        return switch(mapType) {
        case 0: .standard(elevation: .realistic)
        case 1: .hybrid
        case 2: .imagery
        default: .standard(elevation: .realistic)
        }
    }

    var body: some View {

        VStack {

            Map() {
                Marker(item.entryCatName ?? "", coordinate: coordinate)
                    .tint(.red)
            }
            .mapStyle(selectedMapStyle)

            ShowMapPicker(item: item, mapType: $mapType)
            ShowDetails(item: item)
        }
    }
}
Answered by galen7Smith in 768856022

Searching around the web I found a site showing how to initialize the map view with Map(initialPosition: .region(MKCoordinateRegion(center: span()))

struct DetailPortView: View {

    var item: TravelEntries
    @Binding var mapType: Int

    var coordinate: CLLocationCoordinate2D {
        CLLocationCoordinate2D(
            latitude: item.entryLat,
            longitude: item.entryLong
        )
    }

    var selectedMapStyle: MapStyle {
        return switch(mapType) {
        case 0: .standard(elevation: .realistic)
        case 1: .hybrid(elevation: .realistic)
        case 2: .imagery(elevation: .realistic)
        default: .standard(elevation: .realistic)
        }
    }

    var body: some View {

        VStack {

            Map(initialPosition: .region(MKCoordinateRegion(center: coordinate, span: (MKCoordinateSpan(latitudeDelta: 0.005, longitudeDelta: 0.005))))) {

                Marker("\(item.entryCatName ?? "") purchase", coordinate: coordinate)
                    .tint(.red)


            }
            .mapStyle(selectedMapStyle)

            ShowMapPicker(item: item, mapType: $mapType)
            ShowDetails(item: item)
        }
    }
}

I have discovered that if I add a .safeAreaInset containing a button I can then add a camera region with latitudeMeters / longitudeMeters (span): .safeAreaInset(edge: .bottom) { Button { camera = .region(MKCoordinateRegion(center: coordinate, latitudinalMeters: 750, longitudinalMeters: 750)) } label: { Text("Button") } But I don't want the user to have to hit another button for the span to get set properly. Any ideas on how to do that?

Accepted Answer

Searching around the web I found a site showing how to initialize the map view with Map(initialPosition: .region(MKCoordinateRegion(center: span()))

struct DetailPortView: View {

    var item: TravelEntries
    @Binding var mapType: Int

    var coordinate: CLLocationCoordinate2D {
        CLLocationCoordinate2D(
            latitude: item.entryLat,
            longitude: item.entryLong
        )
    }

    var selectedMapStyle: MapStyle {
        return switch(mapType) {
        case 0: .standard(elevation: .realistic)
        case 1: .hybrid(elevation: .realistic)
        case 2: .imagery(elevation: .realistic)
        default: .standard(elevation: .realistic)
        }
    }

    var body: some View {

        VStack {

            Map(initialPosition: .region(MKCoordinateRegion(center: coordinate, span: (MKCoordinateSpan(latitudeDelta: 0.005, longitudeDelta: 0.005))))) {

                Marker("\(item.entryCatName ?? "") purchase", coordinate: coordinate)
                    .tint(.red)


            }
            .mapStyle(selectedMapStyle)

            ShowMapPicker(item: item, mapType: $mapType)
            ShowDetails(item: item)
        }
    }
}
Implementing Map Span in iOS 17
 
 
Q