Map(initialPosition: .camera(mapCamera)) {
Marker("Here", coordinate: location)
}
.frame(height: 300)
.clipShape(RoundedRectangle(cornerSize: CGSize(width: 10, height: 10)))
.onMapCameraChange(frequency: .continuous) { cameraContext in
locationManager.location = cameraContext.camera.centerCoordinate
}
.onReceive(locationManager.$location, perform: { location in
if let location {
mapCamera.centerCoordinate = location
}
})
class LocationDataManager: NSObject, CLLocationManagerDelegate, ObservableObject {
enum LoadingState {
case loading
case notLoading
case finished
}
static let shared = LocationDataManager()
private let locationManager = CLLocationManager()
@Published var location: CLLocationCoordinate2D? = nil
@Published var loading: LoadingState = .notLoading
override init() {
super.init()
locationManager.delegate = self
}
func resetLocation() {
loading = .notLoading
location = nil
}
func getLocation() {
locationManager.requestLocation()
loading = .loading
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
location = locations.first?.coordinate
if location != nil {
loading = .finished
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: any Error) {
print("Failed to retrieve location: \(error.localizedDescription)")
loading = .notLoading
}
}
So the when the LocationButton is selected, the location is found and the marker is set correctly. You can also move the camera around to adjust the marker position, which works correctly. However, if you press the LocationButton again, it updates the marker position but it won't move the MapCamera to the new location. I can see the marker move. mapCamera.centerCoordinate = location
should be doing it, but it's not. Anyone know how to fix this?
I figured it out. You have to use mapCameraKeyframeAnimator().
@State private var centerCoordinate = CLLocationCoordinate2D(latitude: 38.9072, longitude: -77.0369)
@State private var distance: CLLocationDistance = 1000000
@State private var triggerCamera = false
Map(initialPosition: .camera(MapCamera(centerCoordinate: centerCoordinate, distance: distance))) {
}
.frame(height: geo.size.height * 0.60)
.shadow(color: .black.opacity(0.5), radius: 1, y: 1)
.onReceive(locationManager.$location, perform: { location in
if let location {
centerCoordinate = location
triggerCamera = true
}
})
.mapCameraKeyframeAnimator(trigger: triggerCamera, keyframes: { camera in
KeyframeTrack(\MapCamera.centerCoordinate, content: {
LinearKeyframe(centerCoordinate, duration: 1)
})
KeyframeTrack(\MapCamera.distance, content: {
LinearKeyframe(300, duration: 1)
})
})
Updating the trigger to true will start the animation, which moves to the provided location.