How to open call out MKAnnotationView programmatically? (iPhone, MapKit) - iphone

I want to open up the callout for an MKPinAnnotationView programmatically. Eg I drop 10 pins on the map, and want to open up the one closest to me. How would I go about doing this?
Apple has specified the 'selected' parameter for MKAnnotationView's, but discourages setting it directly (this doesn't work, tried it).
For the rest MKAnnotationView only has a setHighlighted (same story), and can ShowCallout method..
Any hints if this is possible at all?

In your mapViewController create an action method:
- (void)openAnnotation:(id)annotation
{
//mv is the mapView
[mv selectAnnotation:annotation animated:YES];
}
You can then determine the closest annotation based on current location and walking the annotations available in the array.
[mv annotations];
Once the closest annotation is calculated, call:
[self openAnnotation:closestAnnotation];
The mapView should scroll automatically to place your annotation in the center of the display area.

In swift 3 this is updated to:
func openAnnotation(annotation: MkAnnotation) {
_ = [mapView .selectAnnotation(annotation, animated: true)]
}
and can be called using any annotation (this will open the annotation callout view and attempt to center the annotation on the map)
For example using the second annotation in a hypothetical list of annotations.
openAnnotation(annotation: mapView.annotations[1])

Related

MapKit - iOS 13 - How to show pin annotations on top on the user location annotation?

Currently, when I try to add an annotation to the map in the user's location the annotation is not showing up. When I set the annotation (using the same code) besides the user's location it does show up.
The code:
let annotation = MKPointAnnotation()
annotation.coordinate = coordinate // set coordinate
annotation.title = "Title"
annotation.subtitle = "Subtitle"
mapView.addAnnotation(annotation)
same issue here, it was working fine with iOS 12, now all annotations near the current location marker are not visible anymore. Critical information might be near the user location and needs to be displayed. This is mostly bad when you zoom out the map, as you don't know anymore if there is data since all annotations comes near the user location...
Is there a document that indicates this change from apple? I didn't find any... thanks in advance for someone that finds it.
If there is no options to turn off this behavior, the only workaround I can think of is to manually add the current location annotation ourselves...
In the callback -mapView:viewForAnnotation on your MKMapViewDelegate be sure that the MKAnnotationView you return leaves its displayPriority as its default value which is MKFeatureDisplayPriorityRequired otherwise MapKit clusters your annotation view with the user location.
I have a fix for those having issues. I was having issues in my production app as well because I was just adding the annotations to the map and never calling the viewForAnnoation method. I created a sample project and uploaded it to Github so you can review the code and see what I did. In short, you need to create a class that subclasses NSObject and conforms to the MKAnnotation protocol. If using MKLocalsearch like my project, pass the MKMapItem object back and create a new instance of the new class. You will also need to create a class and subclass MKMarkerAnnotationView.
class CustomMKMarkerSubclass: MKMarkerAnnotationView {
override var annotation: MKAnnotation? {
willSet {
if let _ = newValue as? MapLocation {
displayPriority = MKFeatureDisplayPriority.required
canShowCallout = true
}
}
}
}
For more detail, check the project below.
MapKit Demo Project
Using MKPinAnnotationView instead of MKAnnotationView has fixed my issue
- (MKAnnotationView *)mapView:(MKMapView *)tempMapView viewForAnnotation:(id <MKAnnotation>)tempAnnotation{
if ([tempAnnotation isKindOfClass:[MKUserLocation class]]){
return nil;
}
NSString *identifer = #"Identifer";
MKPinAnnotationView *dPV = [[MKPinAnnotationView alloc] initWithAnnotation:tempAnnotation reuseIdentifier:identifer];
[dPV setSelected:YES];
[dPV setTag:102];
dPV.canShowCallout = YES;
[dPV setSelected:YES];
dPV.draggable = YES;
return dPV;}
It seems like iOS 14 fixed this issue

Remove MKAnnotation from MapView

Ok, I can add pin on my map by LongPress on any place of map. Now I need to delete pins. So I want next: when I click on my pin, appear the name of pin and a little button with cross ((X) like in all apps to close), when user will click this button (X) - pin must be deleted. Can I do this? Or maybe there is another simple way to delete pin for user without go to detailview about this pin?
For remove all annotation use this code.
[yourMapView removeAnnotation:yourMapView.annotations];
For remove one annotation just implement logic For example...
First remove all annotation and also remove your selected pin data from the array and after add this new array and add annotation..
// REMOVING ALL ANNOTATION
for (id <MKAnnotation> myAnnot in [objMapView annotations])
{
if (![myAnnot isKindOfClass:[MKUserLocation class]])
{
[objMapView removeAnnotation:myAnnot];
}
}

MapView annotation View without Clicking

In my application show Multiple Annotation between two city but when we move one Annotation to other (with map region set on next previous Button) how to show Annotation detail automatic without clicking on it???
you can test with the title of the annotation, if it mach, you can use
selectAnnotation: animated:
to show the Annotation ( you can subclass MKAnnotation and add an id for test instead title ):
for (id<MKAnnotation> annotation in mapView.annotations)
{
if( [annotation.title isEqualToString:title]) [mapView selectAnnotation:annotation animated:YES];
}

MKMapView (annotations & locations) - iPhone development

How can I determine the coordinates of a certain spot?
How can I create a pin for 1 specific location after knowing it's coordinates? Is creating a new class for that necessary?
ex- PIN to : latitude = 37.786996;
longitude = -122.440100;
To add a basic pin at a given coordinate, the simplest way in iOS 4+ is to use the pre-defined MKPointAnnotation class (no need to define your own class) and call addAnnotation:.
If you need to define your own annotation class because you need some custom properties, don't use the classes shown in the MapCallouts sample app as a basis. They give the false impression that you need to define a separate class for each unique coordinate. Instead, create a class that implements the MKAnnotation protocol but with a settable coordinate property.
Edit:
An example with MKPointAnnotation:
MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
annotation.coordinate = CLLocationCoordinate2DMake(33, 35);
annotation.title = #"Title";
annotation.subtitle = #"Subtitle";
[mapView addAnnotation:annotation];
[annotation release];
If you need to easily access the annotation in other methods in the class, you can make it an ivar instead.
You implement an object that supports the MKMapAnnotation protocol. This object you add to your mkmapview with the "addAnnotation:" call. This will give you the default pin on the map.
If you want to customize the pin you need to implement the MKMapViewDelegate protocol to return an MKAnnotationView with a custom image.

show map callout through code in iPhone

I have tried several things but am unable to solve it out.
I have 10 custom annotations on the map depending upon the area visible.
Now I have 2 buttons next and previous. Clicking on which the callout of annotation must get displayed.
i.e if i click on next buton then callout of annotation 1 will appear and when i click next again then the callout of first will hide and callout of second will appear.
I have tried out
[self.mapView selectAnnotation:self.nextSelectedAnnotationView.annotation animated:YES]
and
[self.mapView deselectAnnotation:self.selectedAnnotationView.annotation animated:YES];
But the main problem is how to get the annotation here??
I have tried NSArray* selectedAnnotations=self.mapview.annotations to get the annotations array
id annotationView =[selectedAnnotations objectAtIndex:i];
[self.mapView selectAnnotation:annotationView animated:YES];
But no luck :(
Any other way to solve my issue.??
it may help you.
NSArray *selectedAnnotations = mapView.selectedAnnotations;
for(id annotationView in selectedAnnotations) {
[mapView deselectAnnotation:[annotationView annotation] animated:NO];
}