Reputation: 7605
I have an MKMapView
where I'm showing annotations and the location informations are coming from an API. I've added a button which will trigger getting data from the API and showing corresponding annotations in the map view. 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.
But after going through different delegate methods of CLLocationManagerDelegate
and MKMapViewDelegate
, I couldn't find any useful solution to my requirement. 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. From the locationManager(_:didUpdateLocations:)
delegate method I'm setting the region for map view:
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. The API needs a location and a radius for sending data back.
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.
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?
Here is how the findPlaces(withType:)
is implemented:
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)
}
}
}
}
Upvotes: 0
Views: 1011
Reputation: 773
Try getting location information and setting annotation in func mapView(MKMapView, regionDidChangeAnimated: Bool) method
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")
}
Upvotes: 0