我有一个基于地图的应用,所以我想为地图的当前位置提供一个应用范围的属性。
我正在SceneDelegate中对其进行初始化
let currentPosition = CurrentPosition()
let mainView = MainView(appState: AppState(), selectedWeatherStation: nil).environmentObject(currentPosition)
我在MainView
中将其声明为@EnvironmentObject
struct MainView: View {
@State var appState: AppState
@State var selectedWeatherStation: WeatherStation? = nil
@EnvironmentObject var currentPosition: CurrentPosition
并且我将其注入我的UIViewRepresentable
孩子中
MapView(weatherStations: $appState.appData.weatherStations,
selectedWeatherStation: $selectedWeatherStation).environmentObject(currentPosition)
.edgesIgnoringSafeArea(.vertical)
在MapView
中
struct MapView: UIViewRepresentable {
@Binding var weatherStations: [WeatherStation]
@Binding var selectedWeatherStation: WeatherStation?
@EnvironmentObject var currentPosition: CurrentPosition
我有一个最终的子类
final class Coordinator: NSObject, MKMapViewDelegate {
@EnvironmentObject var currentPosition: CurrentPosition
作为我的mapview委托,我要在其中更新currentPosition
func mapViewDidChangeVisibleRegion(_ mapView: MKMapView) {
currentPosition = CurrentPosition(northEast: mapView.northEastCoordinate, southWest: mapView.southWestCoordinate)
}
但是此作业currentPosition = CurrentPosition(northEast: mapView.northEastCoordinate, southWest: mapView.southWestCoordinate)
会抛出一个错误Cannot assign to property: 'currentPosition' is a get-only property
而且我真的不知道我在做什么错。
目的是每次用户移动地图时都会更新位置,以便我可以使用当前坐标向我的API执行请求。
CurrentPosition声明如下
class CurrentPosition: ObservableObject {
@Published var northEast = CLLocationCoordinate2D()
@Published var southWest = CLLocationCoordinate2D()
init(northEast: CLLocationCoordinate2D = CLLocationCoordinate2D(), southWest: CLLocationCoordinate2D = CLLocationCoordinate2D()) {
self.northEast = northEast
self.southWest = southWest
}
}
[您需要center
设置地图位置,NE和SW角是主观的,因为它们会随着屏幕尺寸,位置(横向与纵向),缩放等而变化。
您可以从地图的center
和span
中计算它们。
尝试启动此代码,以便您可以了解它们如何相互影响。
import SwiftUI
import MapKit
class MapViewController: ObservableObject {
@Published var center: CLLocationCoordinate2D = CLLocationCoordinate2D()
@Published var latitudeDelta:CLLocationDegrees = CLLocationDegrees()
@Published var longitudeDelta:CLLocationDegrees = CLLocationDegrees()
var southWest: CLLocationCoordinate2D{
get{return CLLocationCoordinate2D(latitude: -(latitudeDelta/2) + center.latitude, longitude: -(longitudeDelta/2) + center.longitude)}
}
var northEast: CLLocationCoordinate2D{
get{return CLLocationCoordinate2D(latitude: (latitudeDelta/2) + center.latitude, longitude: (longitudeDelta/2) + center.longitude)}
}
func resetCenter(){
center = CLLocationCoordinate2D()
}
}
struct CustomMapView: View {
@ObservedObject var mapCont: MapViewController = MapViewController()
@State var refresh: Bool = false
var body: some View {
VStack {
CustomMap(mapCont: mapCont, refresh: $refresh)
HStack {
VStack {
HStack{
Text(String(format: "Center Lat: %.4f", self.mapCont.center.latitude))
Spacer()
Text(String(format: "Center Lon: %.4f", self.mapCont.center.longitude))
}
HStack{
Text("LatDelta = \(self.mapCont.latitudeDelta)")
Spacer()
Text("LonDelta = \(self.mapCont.longitudeDelta)")
}
HStack{
Text("SW Lat = " + String(format: " %.4f",self.mapCont.southWest.latitude))
Spacer()
Text("SW Lat =" + String(format: " %.4f",self.mapCont.southWest.longitude))
}
HStack{
Text("NE Lat = " + String(format: " %.4f",self.mapCont.northEast.latitude))
Spacer()
Text("NE Lat = " + String(format: " %.4f",self.mapCont.northEast.longitude))
}
}
Spacer()
Button("Reset") {
print("resetButton")
self.mapCont.resetCenter()
self.refresh.toggle()
print("resetButton :: center = \(self.mapCont.center)")
}
}.padding(.horizontal)
}
}
}
struct CustomMap: UIViewRepresentable {
var mapCont: MapViewController
@Binding var refresh: Bool
func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView()
mapView.delegate = context.coordinator
return mapView
}
func updateUIView(_ uiView: MKMapView, context: Context) {
print("update")
uiView.centerCoordinate = self.mapCont.center
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, MKMapViewDelegate {
var parent: CustomMap
func mapViewDidChangeVisibleRegion(_ mapView: MKMapView) {
self.parent.mapCont.center = mapView.centerCoordinate
self.parent.mapCont.latitudeDelta = mapView.region.span.latitudeDelta
self.parent.mapCont.longitudeDelta = mapView.region.span.longitudeDelta
}
init(_ parent: CustomMap) {
self.parent = parent
}
}
}
struct CustomMapView_Previews: PreviewProvider {
static var previews: some View {
CustomMapView()
}
}