How can I know if an annotation is already on the mapview - swift

I trying to add annotation pin to Mapview if and only if there is no such same pin already on mapview to avoid having multiple repeat annotations at the same location.
Any one can show me help?

You can use mapView.view(for:) method.
e.g.
if (self.mapView.view(for: annotation) != nil) {
print("pin already on mapview")
}

The approach suggested by #Kosuke Ogawa would work. However it is not a good idea to rely on the UI determine application state.
For eg: You most probably have a list of annotations stored in some sort of data structure in your view controller (I am guessing an Array). This data structure should be the source of truth.
In your case, to determine if a an Annotation is already on the map, check if the Data structure that feeds the mapview contains the annotation and proceed.

Related

How to remove country/state names from MKMapview

I want to remove country / state names from MKMapview in iPhone. Means I need only blank map view without any name on it. Is this possible with MKMapview or any other third party maps.
I want to use this functionality with MKMapTypeStandard map type.
Have a look at MKMapViews property mapType MKMapTypeSatellite. Setting this type you will see a map without any names on it. See the docs:
MkMapView Class Reference
Code:
self.map.mapType = MKMapTypeSatellite;

iOS - using MapKit with plist annotations - how do I search within a position radius

I have an application that uses the Mapkit with a plist that contains my custom annotations. This all works fine.
What I next want to do outside of the map is to be able to locate all the custom annotations that are with say a 10 mile radius of my location or a location I select.
I simply want to return the list of annotations that meet that criteria and present them in a list view.
Any ideas what would be the best way of doing this?
If you create CLLocation objects out of your data, which you must be capable of doing if you;re able to get them to your map, you can then compare their distances to the location of your choice using distanceFromLocation

Is a MKAnnotation pin connected to the object that holds it? How do I trace back?

I have a NSObject class "MyItem" that holds several instance variables, among them a mapPoint declared in (MyMapPoint *)mapPoint. I use this MKMapPoint to add annotations to a MKMapView. The NSMutablearray "allItems" holds all items.
int all =[allItems count];
int i =0;
for (i=0; i<all; i++) {
MyItem *p = [allItems objectAtIndex:i];
[mYView addAnnotation:[p mapPoint]];
This works perfect. I get a map full of pins where the items were registered. Also, I get a bubble when I push the pin, which gives title and subtitle. I have also managed to add a callout to the console.
NSLog (#"bubble is pushed");
which also works fine.
Problem: When I push the bubble, I want (to begin with) the console to log the full description of the actuall item the pin represents. Is there any sample code that traces back the to full MyItem? It seems like the pin has no recollection of its origin. All help, samplecode and links to samplecode will be heavilly appriciated.
It sounds like you've got a separate type for your annotations (i.e. whatever is returned by the -mapPoint method). An easier way to deal with this is to implement the MKAnnotation protocol directly in your MyItem class. That way, instead of:
[mYView addAnnotation:[p mapPoint]];
you can just say:
[mYView addAnnotation:p];
By adopting MKAnnotation in your data object, you get direct access to the data you need when the user taps an annotation view.
Another way to go, of course, is to stash a pointer back to your data object in you annotation. That can make more sense if your data objects are large, or if you have very many of them. It doesn't even really have to be an actual object pointer -- you just need to store some piece of information in your annotation that lets you later recover the data object. So, for example, you might include an identifier in your annotation. When the user taps the annotation view, you use the identifier to retrieve the associated data from your data store.
Short answer: You're responsible for connecting your annotations to your data; the framework doesn't do it for you.

Searching for particular MKAnnotation class in MKMapView

I have 4-5 kinds of different annotations classes in mapView.
With following code I expect only AnnotationType1 should respond to for loop.
for (AnnotationType1* annotation in mymap.annotations)
{
NSLog(#"annotation class is %#", [annotation class]);
}
But as is evident from console I get other classes also.
annotation class is AnnotationType1
annotation class is AnnotationType2
annotation class is AnnotationType3
annotation class is AnnotationType4
what will be the best way to perform actions only on say AnnotationType1 annotation?
First, as you've discovered, fast iteration doesn't work the way you thought it did. mymap.annotations returns the same array of annotation objects no matter what -- it doesn't have any idea what kind of pointer you're assigning them to.
Second, it's usually considered a bad idea to count on a view (such as MKMapView) to store data (like your annotations). It's fine for the map view to know about the annotations -- it must know about them to do its job properly. But I wouldn't recommend counting on the map view to maintain the app's state. You probably have the annotation objects stored somewhere in your data model -- if so, that'd be a better place to get the list of annotations.
Third, you can filter the array using a predicate. See this answer for help using a predicate to filter by class name.

Updating MKMapView Annotations from Updated array?

I am working with an NSMutableArray of objects that conform to the MKAnnotation protocol. My question is over time new objects are added to the array, can anyone tell me what is the preferred method for updating the annotations on the mapView. Should I be looking at removing all the pins before adding back the updated array, or would I be better to mark/tag existing pins in the MKAnnotation object and only add back the new (un-tagged) pins?
Removing all the pins and adding back the whole array including the new annotations will result in flicker and unnecessarily redrawing pins that haven't changed.
Unless the flicker is desired or a full refresh is necessary for some reason, it's better to just tell the map view to add the new pins.
After your main annotation array is updated with the new pins, construct a temporary array called say newAnnots containing references to the new annotations in the main array and pass newAnnots to the map view's addAnnotations: method. The temporary array can be discarded afterwards.
However, instead of using tagging to identify "new" annotations, you could just check if the annotation object in your main array already exists in the map view's annotations array. For example:
if (![mapView.annotations containsObject:annot_from_your_main_array]) {
[newAnnots addObject:annot_from_your_main_array];
}
Comparing with the map view's annotations array will only work if the annotation objects in your main array are the actual annotations you give to the map view in addAnnotation: or addAnnotations:. Also, when your main array is "updated", it should only add the new annotations instead of rebuilding the whole array from scratch. If it does, the annotation references won't match with the ones in the map view's array.
The same applies if you are removing annotations on an update. The removed annotations could be added to a temporary "remove" list (by checking if annotations in the map view's array exist in your array) and passed to removeAnnotations:.
Note that if you update an existing annotation's coordinates in your main array, the map view will automatically update the pin's location as long as the annotation object in your array implements the setCoordinate: method.