【问题标题】:Using mapViewDidChangeVisibleRegion with CLGeocoder to return name of the country使用带有 CLGeocoder 的 mapViewDidChangeVisibleRegion 返回国家名称
【发布时间】:2020-12-05 00:10:12
【问题描述】:

我只想返回黑圈所在国家的名字。 [1]:https://i.stack.imgur.com/Re5FK.jpg 上图中的例子

我知道它可以通过 CLGeocoderCLPlacemark 以及 Mapkit 来完成,我尝试了很多但总是出错并且应用会崩溃。

我的代码

import MapKit
import SwiftUI

struct MapView: UIViewRepresentable {
    
    @Binding var centralCoordinate: CLLocationCoordinate2D
    var anotations: [MKPointAnnotation]
    
    func makeUIView(context: Context) -> MKMapView{
        let mapview = MKMapView()
        mapview.delegate = context.coordinator
        return mapview
    }
    
    func updateUIView(_ view: MKMapView, context: Context) {
        
        if anotations.count != view.annotations.count {
            view.removeAnnotations(view.annotations)
            view.addAnnotations(anotations)
        }
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    class Coordinator: NSObject, MKMapViewDelegate {
        var parent: MapView
        
        init(_ parent: MapView) {
            self.parent = parent
        }
        
        func mapViewDidChangeVisibleRegion(_ mapView: MKMapView) {

            parent.centralCoordinate = mapView.centerCoordinate

            let geoCoder = CLGeocoder()
            let location = CLLocation(latitude: mapView.centerCoordinate.latitude, longitude: mapView.centerCoordinate.longitude)
            geoCoder.reverseGeocodeLocation(location, completionHandler: { (placemarks, error) -> Void in
                
                // Place details
                var placeMark: CLPlacemark!
                placeMark = placemarks?[1]
                // Country
                if let country = placeMark.country {
                    print(country)
                }
            })
        }
    }
}

extension MKPointAnnotation{
    static var eample: MKPointAnnotation {
        let annotaton = MKPointAnnotation()
        annotaton.title = "London"
        annotaton.subtitle = "Home TO 2012 Summer Olampics"
        annotaton.coordinate = CLLocationCoordinate2D(latitude: 51.5, longitude: -0.13)
        return annotaton
    }
}

struct MapView_Previews: PreviewProvider {
    static var previews: some View {
        MapView(centralCoordinate: .constant(MKPointAnnotation.eample.coordinate), anotations: [MKPointAnnotation.eample])
    }
}

我的查看代码

import  MapKit
import SwiftUI

struct MapViewIntegration: View {
    
    @State private var centercoordinate = CLLocationCoordinate2D()
    @State private var locations = [MKPointAnnotation]()
    
    var body: some View {
        ZStack {
            MapView(centralCoordinate: $centercoordinate,anotations: locations)
        .edgesIgnoringSafeArea(.all)
        Circle()
        .opacity(0.3)
        .frame(width: 32, height: 32)
            VStack{
                Spacer()
                HStack{
                    Spacer()
                    Button(action: {
                        let newLocations = MKPointAnnotation()
                           newLocations.coordinate = self.centercoordinate
                           self.locations.append(newLocations)
                    }) {
                        Image(systemName: "plus")
                    }.padding()
                    .background(Color.white)
                    .font(.title)
                    .clipShape(Circle())
                    .padding(.trailing)
                }
            }
        }
    }
}

struct MapViewIntegration_Previews: PreviewProvider {
    static var previews: some View {
        MapViewIntegration()
    }
}

请帮忙, 提前致谢

【问题讨论】:

  • 你的代码在哪里崩溃,你得到什么错误信息?
  • 它在这行代码上崩溃 ``` if let country = placeMark.country { print(country) } ``` 说“线程 1:致命错误:在隐式展开 Optional 时意外发现 nil价值”
  • 尝试在该行之前打印每个值(placeMark、placeMark.country、国家),看看哪个打印的是 nil。这可能会缩小问题的范围。
  • @SanzioAngeli placeMark 返回 nil 所以 print(placeMark.country) 导致崩溃
  • @SanzioAngeli 感谢您的建议,问题是当我移动地图时,它会向苹果服务器发送太多请求,请求将失败并引发错误,非常感谢您的回答跨度>

标签: swiftui uikit mapkit core-location


【解决方案1】:

这个答案是由@SanzioAngeli 给出的

将此代码替换为

   func mapViewDidChangeVisibleRegion(_ mapView: MKMapView) {

            parent.centralCoordinate = mapView.centerCoordinate

            let geoCoder = CLGeocoder()
            let location = CLLocation(latitude: mapView.centerCoordinate.latitude, longitude: mapView.centerCoordinate.longitude)
            geoCoder.reverseGeocodeLocation(location, completionHandler: { (placemarks, error) -> Void in
                
                // Place details
                var placeMark: CLPlacemark!
                placeMark = placemarks?[1]
                // Country
                if let country = placeMark.country {
                    print(country)
                }
            })
        }
    }

这个

   func mapViewDidChangeVisibleRegion(_ mapView: MKMapView) {

            parent.centralCoordinate = mapView.centerCoordinate

            let geoCoder = CLGeocoder()
            let location = CLLocation(latitude: mapView.centerCoordinate.latitude, longitude: mapView.centerCoordinate.longitude)
            geoCoder.reverseGeocodeLocation(location, completionHandler: { (placemarks, error) -> Void in
                
                // Place details
                var placeMark: CLPlacemark!
                placeMark = placemarks?[0]
                // Country
                if let country = placeMark.country {
                    print(country)
                }
            })
        }
    }

@SanzioAngeli 谢谢。

记住不要一次发送太多请求,所有请求都会失败并抛出致命错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-08
    • 1970-01-01
    • 2014-01-10
    • 1970-01-01
    • 1970-01-01
    • 2017-08-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多