简体   繁体   English

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

[英]Loading data from api and showing annotation after MKMapView's region is successfully set to user's current location

I have an MKMapView where I'm showing annotations and the location informations are coming from an API. 我有一个MKMapView ,其中显示注释,并且位置信息来自API。 I've added a button which will trigger getting data from the API and showing corresponding annotations in the map view. 我添加了一个按钮,该按钮将触发从API获取数据并在地图视图中显示相应的注释。 However, I'm trying to implement such thing: 但是,我正在尝试实现这样的事情:

User lands on the map view scene and the current location gets updated and the region of the map view is set to a specific boundary around the user's location. 用户降落在地图视图场景上,当前位置得到更新,并且地图视图的区域设置为围绕用户位置的特定边界。 After the animation for .setRegion(_:animated:) of the map view completes, some annotations will be shown to user without the user specifically tapping the button for showing annotation. 的动画之后 .setRegion(_:animated:) 地图视图完成的,一些注释将显示给用户而无需特别攻丝表示注释的按钮,用户。

But after going through different delegate methods of CLLocationManagerDelegate and MKMapViewDelegate , I couldn't find any useful solution to my requirement. 但是,在经历了CLLocationManagerDelegateMKMapViewDelegate不同委托方法之后,我找不到满足我需求的任何有用的解决方案。 Sometimes the annotations are added before the animation for region setting completes. 有时,在区域设置动画完成之前会添加注释。 Sometimes they are added after the animation completes. 有时,它们是在动画完成后添加的。

I've used CLLocationManger for getting the user's current location. 我使用CLLocationManger来获取用户的当前位置。 From the locationManager(_:didUpdateLocations:) delegate method I'm setting the region for map view: 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")
}

In the above delegate method, I'm calling findPlaces(withType:) method which will fetch data from API and add annotations to the map. 在上面的委托方法中,我正在调用findPlaces(withType:)方法,该方法将从API提取数据并将注释添加到地图。 The API needs a location and a radius for sending data back. API需要一个位置和一个半径,用于将数据发送回去。

In my mapView(_:regionDidChangeAnimated:) delegate, I'm keeping track of the center position and visible area of the map view which I'll use later when user taps on the Show Here button. 在我的mapView(_:regionDidChangeAnimated:)委托中,我跟踪地图视图的中心位置和可见区域,稍后当用户点击“在此处显示”按钮时将使用它。

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
}

How to show annotations to the user automatically after map view's center is set to the user's current location and the viewable region of the map view is done setting with animation? 在将地图视图的中心设置为用户的当前位置并且使用动画设置完成地图视图的可视区域之后,如何自动向用户显示注释?

This is the nearly expected output: 这是几乎预期的输出:

This is not the output I want: 这不是我想要的输出:

Edit: 编辑:

Here is how the findPlaces(withType:) is implemented: 这是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)
            }
        }
    }
}

Try getting location information and setting annotation in func mapView(MKMapView, regionDidChangeAnimated: Bool) method 尝试获取位置信息并在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")

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM