My app needs to track the user's location but each time my locationManager sends a location update it dismisses a toolbar menu (if it is displayed). The odd thing is that if the menu buttons have empty actions or just a print statement then all is fine but as soon as a method is put in there it dismisses upon the next UI update.
iOS: 17.0
XCode: Version 15.0 beta 3
Background Modes: Location updates
Privacy - Location When In Use Usage Description = You are being watched!
import SwiftUI
@main
struct DetectHelpApp: App {
var locationManager = LocationManager()
var body: some Scene {
WindowGroup {
ContentView()
.environment(locationManager)
}
}
}
import MapKit
import SwiftUI
struct ContentView: View {
@Environment(LocationManager.self) var locationManager
@State private var cameraPosition: MapCameraPosition = .region(MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 51.556000, longitude: -0.279511), latitudinalMeters: 1000, longitudinalMeters: 1000))
var body: some View {
NavigationStack {
Map(position: $cameraPosition) {
UserAnnotation()
}
.onChange(of: locationManager.lastLocation) { oldValue, newValue in
print(locationManager.lastLocation)
withAnimation() {
// If the centre of the map is locked to the user's location, then recompose with the new coordinate.
cameraPosition = .region(MKCoordinateRegion(center: newValue.coordinate, latitudinalMeters: 1000, longitudinalMeters: 1000))
}
} // onChange - end
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Menu("Menu") {
Button("Start") { help() /*print("Start")*/ }
Button("Resume") { print("Resume") }
}
}
}
.navigationTitle("Scooby Doo")
}
}
func help() { }
}
import CoreLocation
import Observation
@Observable
final class LocationManager: NSObject, CLLocationManagerDelegate {
var lastLocation: CLLocation = CLLocation(latitude: 51.556000, longitude: -0.279511)
let locationManager = CLLocationManager()
init(dog: String = "") {
super.init()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = 2
locationManager.requestWhenInUseAuthorization()
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
// Ensure we have an actual location in the update.
guard let location = locations.last else { return }
lastLocation = location // Our published CLLocation.
}
}