Reputation: 113
I was trying to display my current location into a Swiftui MapView. To do so, I created the following class:
import SwiftUI
import CoreLocation
import Combine
class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate {
@Published var locationManager = CLLocationManager()
@Published var locationStatus: CLAuthorizationStatus?
@Published var lastLocation: CLLocation?
override init() {
super.init()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
private var statusString: String {
guard let status = locationStatus else {
return "unknown"
}
switch status {
case .notDetermined: return "notDetermined"
case .authorizedWhenInUse: return "authorizedWhenInUse"
case .authorizedAlways: return "authorizedAlways"
case .restricted: return "restricted"
case .denied: return "denied"
default: return "unknown"
}
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
locationStatus = status
print(#function, statusString)
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.first else { return }
lastLocation = location
// fetchLocation(location: lastLocation)
self.locationManager.stopUpdatingLocation()
print(#function, location)
}
}
and the following view:
var body: some View {
VStack {
Text("Latitude: \(locationManager.lastLocation?.coordinate.latitude ?? 0), Longitude: \(locationManager.lastLocation?.coordinate.longitude ?? 0)")
.onAppear{
print("DEBUG: status 1 : \(locationManager.lastLocation?.coordinate.latitude ?? 0)")
}
MapView(lat: (locationManager.lastLocation?.coordinate.latitude ?? 0), lon: locationManager.lastLocation?.coordinate.longitude ?? 0, latDelta: 0.05, lonDelta: 0.05)
.frame(width: UIScreen.screenWidth - 36, height: UIScreen.screenWidth / 2)
.cornerRadius(10)
.onAppear{
print("DEBUG: status 2 : \(locationManager.locationStatus)")
print("DEBUG: lat: \(locationManager.lastLocation?.coordinate.latitude), lon: \(locationManager.lastLocation?.coordinate.longitude)")
}
}
}
So far, the Textfield does show the correct coordinates, but my Mapview shows NIL as the coordinates.
Adding my MapView here as well for completeness:
struct MapView: UIViewRepresentable {
@State var lat = 0.0
@State var lon = 0.0
@State var latDelta = 0.05
@State var lonDelta = 0.05
func makeUIView(context: Context) -> MKMapView {
MKMapView(frame: .zero)
}
func updateUIView(_ uiView: MKMapView, context: Context) {
let coordinate = CLLocationCoordinate2D(latitude: lat, longitude: lon )
let span = MKCoordinateSpan(latitudeDelta: latDelta, longitudeDelta: lonDelta)
let region = MKCoordinateRegion(center: coordinate, span: span)
uiView.setRegion(region, animated: true)
}
}
Hope you could have a look and see if I have missed anything.
Upvotes: 0
Views: 307
Reputation: 113
The answer is:
Remove all the @State from the MapView():
struct MapView: UIViewRepresentable {
var lat = 0.0
var lon = 0.0
var latDelta = 0.05
var lonDelta = 0.05
func makeUIView(context: Context) -> MKMapView {
MKMapView(frame: .zero)
}
func updateUIView(_ uiView: MKMapView, context: Context) {
let coordinate = CLLocationCoordinate2D(latitude: lat, longitude: lon )
let span = MKCoordinateSpan(latitudeDelta: latDelta, longitudeDelta: lonDelta)
let region = MKCoordinateRegion(center: coordinate, span: span)
uiView.setRegion(region, animated: true)
}
}
Upvotes: 0