这是我发现的设置CoreLocation和MapView最干净的方法。首先,您必须创建一个UIViewRepresentable,在SwiftUI中使用CoreLocation。
不要忘记在Info.plist文件中启用此隐私并添加以下信息:
隐私-始终和在使用时使用位置描述
隐私-仅在使用时使用位置描述
隐私-始终使用位置描述
import SwiftUI
import MapKit
struct MapView: UIViewRepresentable {
@Binding var locationManager: CLLocationManager
@Binding var showMapAlert: Bool
let map = MKMapView()
func makeUIView(context: Context) -> MKMapView {
locationManager.delegate = context.coordinator
return map
}
func updateUIView(_ view: MKMapView, context: Context) {
map.showsUserLocation = true
map.userTrackingMode = .follow
}
func makeCoordinator() -> MapView.Coordinator {
return Coordinator(mapView: self)
}
class Coordinator: NSObject, CLLocationManagerDelegate {
var mapView: MapView
init(mapView: MapView) {
self.mapView = mapView
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
switch status {
case .restricted:
break
case .denied:
mapView.showMapAlert.toggle()
return
case .notDetermined:
mapView.locationManager.requestWhenInUseAuthorization()
return
case .authorizedWhenInUse:
return
case .authorizedAlways:
mapView.locationManager.allowsBackgroundLocationUpdates = true
mapView.locationManager.pausesLocationUpdatesAutomatically = false
return
@unknown default:
break
}
mapView.locationManager.startUpdatingLocation()
}
}
}
}
以下是翻译的结果:
这是我在SwiftUI视图中使用它的方式。如果权限被Coordinator类切换拒绝,警报将被切换:
import SwiftUI
import CoreLocation
struct HomeView: View {
@State var locationManager = CLLocationManager()
@State var showMapAlert = false
var body: some View {
MapView(locationManager: $locationManager, showMapAlert: $showMapAlert)
.alert(isPresented: $showMapAlert) {
Alert(title: Text("Location access denied"),
message: Text("Your location is needed"),
primaryButton: .cancel(),
secondaryButton: .default(Text("Settings"),
action: { self.goToDeviceSettings() }))
}
}
}
extension HomeView {
func goToDeviceSettings() {
guard let url = URL.init(string: UIApplication.openSettingsURLString) else { return }
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
}
当前方案->编辑->运行->选项->允许位置模拟
。 - Matteo Pacini