【发布时间】:2020-05-01 01:47:59
【问题描述】:
尝试更新 Project 14 of 100daysOfSwiftUI 的地图视图以显示我当前的位置,问题我无法放大移动
我有这段代码,我将 @Binding var currentLocation : CLLocationCoordinate2D 和 view.setCenter(currentLocation, animated: true) 添加到我的 MapView 中,所以我有一个按钮可以发送该值,并且视图实际上移动到该位置的速度非常慢,但我可以再离开
import SwiftUI
import MapKit
struct MapView: UIViewRepresentable {
@Binding var centerCoordinate: CLLocationCoordinate2D
@Binding var selectedPlace: MKPointAnnotation?
@Binding var showingPlaceDetails: Bool
@Binding var currentLocation : CLLocationCoordinate2D
var annotations: [MKPointAnnotation]
func makeUIView(context: Context) -> MKMapView {
let mapView = MKMapView()
mapView.delegate = context.coordinator
return mapView
}
func updateUIView(_ view: MKMapView, context: Context) {
if annotations.count != view.annotations.count {
view.removeAnnotations(view.annotations)
view.addAnnotations(annotations)
}
view.setCenter(currentLocation, animated: true)
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, MKMapViewDelegate{
var parent: MapView
init(_ parent: MapView) {
self.parent = parent
}
func mapViewDidChangeVisibleRegion(_ mapView: MKMapView) {
parent.centerCoordinate = mapView.centerCoordinate
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let identifier = "PlaceMark"
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier)
if annotationView == nil {
annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
annotationView?.canShowCallout = true
annotationView?.rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
} else {
annotationView?.annotation = annotation
}
return annotationView
}
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
guard let placemark = view.annotation as? MKPointAnnotation else {return}
parent.selectedPlace = placemark
parent.showingPlaceDetails = true
}
}
}
这是我的 swiftUI 视图
...
@State private var currentLocation = CLLocationCoordinate2D()
var body: some View {
ZStack{
MapView(centerCoordinate: $centerCoordinate, selectedPlace: $selectedPlace, showingPlaceDetails: $showingPlaceDetails, currentLocation: $currentLocation , annotations: locations)
// MapView(centerCoordinate: $centerCoordinate, selectedPlace: $selectedPlace, showingPlaceDetails: $showingPlaceDetails, annotations: locations)
.edgesIgnoringSafeArea(.all)
VStack{
Spacer()
HStack{
Spacer()
Button(action: {
self.getCurrentLocation()
}){
ButtonIcon(icon: "location.fill")
}
}
.padding()
}
}
.onAppear(perform: getCurrentLocation)
}
func getCurrentLocation() {
let lat = locationManager.lastLocation?.coordinate.latitude ?? 0
let log = locationManager.lastLocation?.coordinate.longitude ?? 0
self.currentLocation.latitude = lat
self.currentLocation.longitude = log
}
...
更新
感谢支持我使用这个课程拨打locationManager.requestWhenInUseAuthorization()
import Foundation
import CoreLocation
import Combine
class LocationManager: NSObject, ObservableObject {
override init() {
super.init()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
}
@Published var locationStatus: CLAuthorizationStatus? {
willSet {
objectWillChange.send()
}
}
@Published var lastLocation: CLLocation? {
willSet {
objectWillChange.send()
}
}
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"
}
}
let objectWillChange = PassthroughSubject<Void, Never>()
private let locationManager = CLLocationManager()
}
extension LocationManager: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
self.locationStatus = status
print(#function, statusString)
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.last else { return }
self.lastLocation = location
print(#function, location)
}
}
当我按下按钮时,我只想将我的地图视图集中在我当前的位置上
【问题讨论】:
-
顺便说一句,如果你原谅我指出这一点,但如果下次你能提供一个完整的例子就好了(例如这个
lastLocation属性是什么?;一些@ 987654328@ 属性丢失;等等)并删除不必要的东西(例如,我们真的需要ButtonIcon对象吗?我们需要注释相关的代码吗?)。我们通常想做的第一件事,尤其是遇到如此复杂的问题,就是尝试重现您的问题,而您却很难做到这一点。这里不用担心,但为了将来参考...... -
@Rob 谢谢我刚刚添加了我管理位置权限的类,lastLocation 是
CLLocation?