120 lines
4 KiB
Swift
120 lines
4 KiB
Swift
import CoreLocation
|
|
import MapKit
|
|
import SwiftUI
|
|
import UIKit
|
|
|
|
struct AttachmentLocationPickerView: View {
|
|
@StateObject private var locationManager = LocationManager()
|
|
@State private var region = MKCoordinateRegion(
|
|
center: CLLocationCoordinate2D(latitude: 34.011_286, longitude: -116.166_868),
|
|
span: MKCoordinateSpan(latitudeDelta: 0.2, longitudeDelta: 0.2)
|
|
)
|
|
@State private var showingAlert = false
|
|
@State private var userInteraction = false
|
|
|
|
var body: some View {
|
|
MapView(coordinateRegion: $region, interactionState: $userInteraction)
|
|
.onAppear {
|
|
locationManager.start()
|
|
}
|
|
.onChange(of: locationManager.lastLocation) { newLocation in
|
|
if let newLocation, !userInteraction {
|
|
region.center = newLocation.coordinate
|
|
}
|
|
}
|
|
.onChange(of: locationManager.authorizationStatus) { newStatus in
|
|
if newStatus == .denied {
|
|
showingAlert = true
|
|
}
|
|
}
|
|
.alert(isPresented: $showingAlert) {
|
|
Alert(
|
|
title: Text("Location Permission Denied"),
|
|
message: Text("Please enable location permissions in settings."),
|
|
dismissButton: .default(Text("OK")) {
|
|
openAppSettings()
|
|
}
|
|
)
|
|
}
|
|
.overlay {
|
|
Image(systemName: "mappin")
|
|
.font(.title)
|
|
.foregroundColor(.Material.Elements.active)
|
|
.padding()
|
|
if userInteraction {
|
|
VStack {
|
|
Spacer()
|
|
HStack {
|
|
Spacer()
|
|
Image(systemName: "location.north.circle.fill")
|
|
.font(.title)
|
|
.foregroundColor(.Material.Elements.active)
|
|
.padding()
|
|
.tappablePadding(.symmetric(10)) {
|
|
userInteraction = false
|
|
region.center = locationManager.lastLocation?.coordinate ?? region.center
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate {
|
|
private let locationManager = CLLocationManager()
|
|
@Published var lastLocation: CLLocation?
|
|
@Published var authorizationStatus: CLAuthorizationStatus
|
|
|
|
override init() {
|
|
authorizationStatus = locationManager.authorizationStatus
|
|
super.init()
|
|
locationManager.delegate = self
|
|
}
|
|
|
|
func start() {
|
|
locationManager.requestWhenInUseAuthorization()
|
|
locationManager.startUpdatingLocation()
|
|
}
|
|
|
|
func locationManager(_: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
|
|
lastLocation = locations.first
|
|
}
|
|
|
|
func locationManager(_: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
|
|
authorizationStatus = status
|
|
}
|
|
}
|
|
|
|
struct MapView: UIViewRepresentable {
|
|
@Binding var coordinateRegion: MKCoordinateRegion
|
|
@Binding var interactionState: Bool
|
|
|
|
func makeUIView(context: Context) -> MKMapView {
|
|
let mapView = MKMapView()
|
|
mapView.delegate = context.coordinator
|
|
mapView.addGestureRecognizer(UIPanGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.mapWasDragged)))
|
|
return mapView
|
|
}
|
|
|
|
func updateUIView(_ uiView: MKMapView, context _: Context) {
|
|
uiView.setRegion(coordinateRegion, animated: true)
|
|
}
|
|
|
|
func makeCoordinator() -> Coordinator {
|
|
Coordinator(self)
|
|
}
|
|
|
|
class Coordinator: NSObject, MKMapViewDelegate {
|
|
var parent: MapView
|
|
|
|
init(_ parent: MapView) {
|
|
self.parent = parent
|
|
}
|
|
|
|
@objc func mapWasDragged() {
|
|
parent.interactionState = true
|
|
}
|
|
}
|
|
}
|