Yes it is possible to change the mapType from hybrid to satellite.
The "trick" is to use an ObservableObject to change the state of the view.
Here is a basic setup that works well for me, passing the
MapModel through an EnvironmentObject. Let us know if this works for you.
import SwiftUI
import Foundation
import MapKit
@main
struct TestApp: App {
var mapModel = MapModel()
var body: some Scene {
WindowGroup {
ContentView().environmentObject(mapModel)
}
}
}
class MapModel: ObservableObject {
@Published var mapType = MKMapType.standard
@Published var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 35.685, longitude: 139.7514), span: MKCoordinateSpan(latitudeDelta: 0.2, longitudeDelta: 0.2))
}
struct ContentView: View {
@EnvironmentObject var mapModel: MapModel
@State private var mapType: Int = 0
@State private var mapTypes = ["Standard", "Satellite", "Hybrid"]
var body: some View {
ZStack (alignment: .topLeading) {
MapView().edgesIgnoringSafeArea(.all)
mapTools
}
}
var mapTools: some View {
HStack {
Spacer()
Picker(selection: Binding<Int> (
get: {self.mapType},
set: {
self.mapType = $0
self.mapModel.mapType = self.getMapType()
}
), label: Text("")) {
ForEach(0 ..< mapTypes.count) {
Text(self.mapTypes[$0])
}
}.pickerStyle(SegmentedPickerStyle())
.labelsHidden()
.frame(width: 222, height: 60)
.clipped()
Spacer()
}
}
func getMapType() -> MKMapType {
switch mapType {
case 0: return .standard
case 1: return .satellite
case 2: return .hybrid
default:
return .standard
}
}
}
struct MapView: UIViewRepresentable {
@EnvironmentObject var mapModel: MapModel
let mapView = MKMapView()
func makeUIView(context: Context) -> MKMapView {
mapView.mapType = mapModel.mapType
mapView.setRegion(mapModel.region, animated: true)
return mapView
}
func updateUIView(_ uiView: MKMapView, context: Context) {
uiView.mapType = mapModel.mapType
}
}