在将MKMapView的区域成功设置为用户的当前位置后,从api加载数据并显示注释

时间:2017-07-27 04:52:44

标签: swift mkmapview cllocationmanager mkmapviewdelegate

我有MKMapView我正在显示注释,位置信息来自API。我添加了一个按钮,它将触发从API获取数据并在地图视图中显示相应的注释。但是,我正在尝试实现这样的事情:

用户登陆地图视图场景并更新当前位置,并将地图视图的区域设置为用户位置周围的特定边界。在地图视图的 .setRegion(_:animated:) 动画完成后,将向用户显示一些注释,而无需用户专门点击按钮以显示注释。

但是在经过CLLocationManagerDelegateMKMapViewDelegate的不同委托方法之后,我找不到任何有用的解决方案来满足我的要求。有时在区域设置动画完成之前添加注释。有时它们会在动画完成后添加。

我使用CLLocationManger来获取用户的当前位置。从locationManager(_:didUpdateLocations:)委托方法我设置地图视图的区域:

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    guard let location = locations.last else { return }
    let span = MKCoordinateSpanMake(0.05, 0.05)
    let region = MKCoordinateRegion(center: location.coordinate, span: span)
    mapView.setRegion(region, animated: true)
    mapView.showsUserLocation = true

    // Remove activity indicator
    effectView.removeFromSuperview()

    // This method is responsible for getting location information from the api and adding annotations to the map view
    findPlaces(withType: "restaurant")
}

在上面的委托方法中,我正在调用findPlaces(withType:)方法,该方法将从API获取数据并向地图添加注释。 API需要一个位置和一个半径来发回数据。

在我的mapView(_:regionDidChangeAnimated:)代表中,我正在跟踪地图视图的中心位置和可见区域,稍后当用户点击 Show Here 按钮。

func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {

    let visibleMapRect = mapView.visibleMapRect
    let leftMapPoint = MKMapPointMake(MKMapRectGetMinX(visibleMapRect), MKMapRectGetMidY(visibleMapRect))
    let rightMapPoint = MKMapPointMake(MKMapRectGetMaxX(visibleMapRect), MKMapRectGetMidY(visibleMapRect))

    mapViewDistance = MKMetersBetweenMapPoints(leftMapPoint, rightMapPoint)
    mapViewCenter = mapView.centerCoordinate
}
  

如何在地图视图的中心设置为用户的当前位置并且地图视图的可视区域设置为动画后自动向用户显示注释?

这几乎是预期的输出:

这不是我想要的输出:

编辑:

以下是findPlaces(withType:)的实施方式:

func findPlaces(withType: String?) {

    // preparing an url from the passed string here
    queryURL = ...

    // get the json data asynchronously
    DataManager.loadData(from: queryURL) { (data, error) in

        if let error = error {
            // Handled error case
        } else {
            do {
                guard let data = data else {
                    // throw error
                }
                let json = try JSONSerialization.jsonObject(with: data, options: [])
                guard let placesDictionary = json as? JSON else {
                    // throw error
                }
                guard let places = Places(json: placesDictionary) else {
                    // throw error
                }
                guard let results = places.results else {
                    // throw error
                }

                // data is fed into results array, now plot this into the map view
                // UI Update should be on the main thread
                DispatchQueue.main.async {
                    self.plotPlaces(with: results)
                }
            } catch {
                print(error)
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

尝试在 func mapView(MKMapView,regionDidChangeAnimated:Bool)方法中获取位置信息和设置注释

func mapView(MKMapView, regionDidChangeAnimated: Bool) {

// This method is responsible for getting location information from the api and adding annotations to the map view.
findPlaces(withType: "restaurant")

}