another.im-ios/ConversationsClassic/View/Screens/Attachments/AttachmentLocationPickerView.swift

120 lines
4 KiB
Swift
Raw Normal View History

2024-07-04 11:45:39 +00:00
import CoreLocation
2024-07-02 09:56:27 +00:00
import MapKit
import SwiftUI
import UIKit
struct AttachmentLocationPickerView: View {
2024-07-04 11:45:39 +00:00
@StateObject private var locationManager = LocationManager()
2024-07-02 09:56:27 +00:00
@State private var region = MKCoordinateRegion(
center: CLLocationCoordinate2D(latitude: 34.011_286, longitude: -116.166_868),
span: MKCoordinateSpan(latitudeDelta: 0.2, longitudeDelta: 0.2)
)
2024-07-04 11:54:09 +00:00
@State private var showingAlert = false
2024-07-04 12:55:47 +00:00
@State private var userInteraction = false
2024-07-02 09:56:27 +00:00
var body: some View {
2024-07-04 12:55:47 +00:00
MapView(coordinateRegion: $region, interactionState: $userInteraction)
2024-07-04 11:45:39 +00:00
.onAppear {
locationManager.start()
}
.onChange(of: locationManager.lastLocation) { newLocation in
2024-07-04 12:55:47 +00:00
if let newLocation, !userInteraction {
2024-07-04 11:45:39 +00:00
region.center = newLocation.coordinate
}
}
2024-07-04 11:54:09 +00:00
.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()
}
)
}
2024-07-04 12:55:47 +00:00
.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
}
}
}
}
}
2024-07-04 11:45:39 +00:00
}
}
class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate {
private let locationManager = CLLocationManager()
@Published var lastLocation: CLLocation?
2024-07-04 11:54:09 +00:00
@Published var authorizationStatus: CLAuthorizationStatus
2024-07-04 11:45:39 +00:00
override init() {
2024-07-04 11:54:09 +00:00
authorizationStatus = locationManager.authorizationStatus
2024-07-04 11:45:39 +00:00
super.init()
locationManager.delegate = self
}
func start() {
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
func locationManager(_: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
lastLocation = locations.first
2024-07-02 09:56:27 +00:00
}
2024-07-04 11:54:09 +00:00
func locationManager(_: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
authorizationStatus = status
}
2024-07-02 09:56:27 +00:00
}
struct MapView: UIViewRepresentable {
@Binding var coordinateRegion: MKCoordinateRegion
2024-07-04 12:55:47 +00:00
@Binding var interactionState: Bool
2024-07-02 09:56:27 +00:00
func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView()
mapView.delegate = context.coordinator
2024-07-04 12:55:47 +00:00
mapView.addGestureRecognizer(UIPanGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.mapWasDragged)))
2024-07-02 09:56:27 +00:00
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
}
2024-07-04 12:55:47 +00:00
@objc func mapWasDragged() {
parent.interactionState = true
2024-07-02 09:56:27 +00:00
}
}
}