How do I update pins on a MKMapView as a user moves - ios

I query a database for store information. I want stores to appear on screen within a certain radius around the user's current location. I want new stores to appear on screen as the user moves without the user having to manually refresh anything. What delegate method should I use to query for stores in and to place them on screen?

you just need to implement only func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? and listen location changes with CLLocation Manager.Whenever new location appear query point of interests and append to mapview by addAnnotations.After than set mapview centerCoordinate property to reveal user current position in mapview

You can get the coordinates of the point at the center of the map using centerCoordinate
var coord: CLLocationCoordinate2D = CLLocationCoordinate2DMake(map.centerCoordinate.latitude, map.centerCoordinate.longitude)

You can have a look at Tracking the User Location for MKMapView using its delegates.
For location update MKMapViewDelagate's
- mapView:didUpdateUserLocation:
To place them on screen remove the previous annotation and add new annotations fetched from your query.

Related

Mapbox (iOS) user annotations covering/preventing touch events from other annotations - use User annotations hit test

I'm having some difficulties with Mapbox iOS.
I'm adding annotations on my map, but when they are very close (actually overlap) to the user annotation (i.e MGLUserLocation) taps do not pass to the other annotations.
I have tried to play with the z-order both for the user annotation (setting it to. 0/-1 or any lower value) while increasing the value of the other annotations but with no success
func mapView(_ mapView: MGLMapView, didSelect annotation: MGLAnnotation)
Is always called with the user annotation.
I'm using a custom view for the user annotation and I tried to set its isEnable property false as well. Moreover, when I try to override the override open func tionsetSelected(_ selected: Bool, animated: Bool) In the custom view it is not called (no matter if it's isEnabled is true/false...)
It seems like the "halo" around the user location annotation make any tap to interact with the user annotation only - even if there are other objects that seems to be before it...
I was thinking as a last option to setup aUIGestureRecognizer on the relevant view that the user annotations "hides"... But am I missing something about the special user annotation in Mapbox?
I create a simple project trying to mimic as best as possible the problem in my original project which is not public - Repo
Here is an example of the capability I'm trying to achieve in Google Maps
Found the solution which I think it is utilising Mapbox API in the best way:
MGLUserLocationAnnotationView has a property called hitTestLayer: CALayer?
You can just override it and supply with the size of the clickable layer you wish to enable.... In my case I don't care for user annotation interaction so I set it to zero (I updated the code in the example repo as well)

Overlapping annotations in MKMapView swift 4

I have a MKMapview view where there are no of annotations. A location entered by the user is considered as current location. I want this current location to be on top of all other annotations.
Right now, the current location is getting ovwerlapped by other annotations.
I have set the current location annotation displaypriority to required in mapView(_ mapView: MKMapView, didAdd views: [MKAnnotationView]) this method.
Please let me know if there is any other way
I dont want the other annotations to disappear. I just want them overlapped with current location annotation.

Why does MKMapView show user's location just as a pin?

I have a mapView in which I want to show user's current location. However, I don't want to centre the mapView to that location (it is centred to other location). So, for that reason, I don't get coordinates for the user's location to set the region. I just call showsUserLocation and set it to true. Everything works fine, except the fact that this makes my mapView show user's current location just as a pin. I would like it to be in a form of a default blue dot.
Related to the problem above, I have two questions:
1) Why does it show user's current location as a pin?
2) How can I make it show user's current location as a blue dot?
If you know the answers to these questions (or only to one of them) I would appreciate your help.
Everything depends on your implementation of the map view delegate's mapView(_:viewFor:). You are probably returning a pin annotation.
You can distinguish the annotation provided by the map view as the user's location by checking its class, which will be MKUserLocation. If you want the default blue dot, return nil for that class.
In Swift 5
We need to check the type of annotation, if it is a user location do not want to return a pin:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
return nil
}
[... code for the other annotations ... ]
}
Now you will see your location as a classic blue dot.

Swift: MKMapView annotation appears in top left corner after a didDeselectAnnotationView call

I'm drawing a MKMapView in my iOS app, and on this map are some annotations, with custom images representing them. The image changes slightly (has a glow) when a specific annotation is selected.
To do this, I'm using the mapView(mapView: MKMapView!, didSelectAnnotationView view: MKAnnotationView!) delegate method to change the image (by changing view.annotation.image). This seems to work fine.
However, when I use the mapView(mapView: MKMapView!, didDeselectAnnotationView view: MKAnnotationView!) method to change the image back after it's deselected, it redraws the annotation in the upper left corner of the map. Any user interaction with the map then redraws it in its proper place immediately, so it's like the map isn't being refreshed after the method call until a click or something is made.
Is this actually the correct way to change an annotation's image (by overwriting the current view.annotation.image, and if so is there a way to refresh the map?
EDIT: I've also just noticed every time I select a new annotation it drags the map center down by about 100 pixels. Is there something I'm missing that I need to do after calling either of these two methods mentioned above?
You could try removing and re-adding the annotation using mapView.removeAnnotation(yourAnnotation) and mapview.addAnnotation(yourAnnotation) with the new image

How to refresh or move pin when user gets current location

I am working on an application which use user location updates, I have got the current latitude and longitude and display the current location of the user and annotate the pin, However I need help regarding moving a pin when user changes his location or when user moves and get new latitude and longitude the pin should also move to that position.
To show the current location, you could just set showsUserLocation to YES and let the map show the blue dot for you.
If you want to show your own annotation instead and have it move automatically, implement setCoordinate: in the class that implements the MKAnnotation protocol.
Then when the coordinates change, update the annotation's coordinate and the map view will automatically (via KVO) move the annotation's view/pin.
You could also remove the annotation and create a new one at the new location but that can result in flicker.
If you are using Core Location to get location updates, you would update the annotation's coordinates in the locationManager:didUpdateToLocation:fromLocation: delegate method.

Resources