How do I display a MKAnnotationView dial peer without touching a pin?

I am working on MKMapView with a regular color buffer as location points. I would like to be able to display the leader without touching the pin.

How should I do it? The call to setSelected:YES in the annotation did nothing. I'm thinking of simulating a touch on a pin, but I'm not sure how to do this.

+73
iphone
Jun 11 '09 at 1:30
source share
13 answers

Ok, here is a solution to this problem.

To display a callout, use the MKMapView selectAnnotation:animated method.

+35
Jun 11 '09 at 6:51
source share

But there is a trick to get benvolioT solution, code

 for (id<MKAnnotation> currentAnnotation in mapView.annotations) { if ([currentAnnotation isEqual:annotationToSelect]) { [mapView selectAnnotation:currentAnnotation animated:FALSE]; } } 

should be called from - (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView and nowhere else.

The sequence in which various methods are called, such as viewWillAppear , viewDidAppear of UIViewController and - (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView , is different from when the map is loaded for the first time with one specific location and subsequent moments when the map is displayed in that same place. This is a bit complicated.

+61
Sep 13 '09 at 18:13
source share

Assuming you want the last annotation view to be selected, you can put the code below:

 [mapView selectAnnotation:[[mapView annotations] lastObject] animated:YES]; 

in the delegate below:

 - (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views { //Here [mapView selectAnnotation:[[mapView annotations] lastObject] animated:YES]; } 
+32
Nov 15 '10 at 2:58
source share

Well, to successfully add a Callout, you must call selectAnnotation: animate after all annotations have been added using the didAddAnnotationViews delegate:

 - (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views{ for (id<MKAnnotation> currentAnnotation in mapView.annotations) { if ([currentAnnotation isEqual: annotationToSelect]) { [mapView selectAnnotation:currentAnnotation animated:YES]; } } } 
+21
May 26 '11 at 22:16
source share

Having tried many answers on this topic, I finally came up with this. It works very reliably, I have not seen it yet:

 - (void)mapView:(MKMapView *)aMapView didAddAnnotationViews:(NSArray *)views; { for(id<MKAnnotation> currentAnnotation in aMapView.annotations) { if([currentAnnotation isEqual:annotationToSelect]) { NSLog(@"Yay!"); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_current_queue(), ^ { [aMapView selectAnnotation:currentAnnotation animated:YES]; }); } } } 

The block is used to delay a bit, since without it, the leader may not display correctly.

+12
Aug 01 2018-12-21T00:
source share

This does not work for me. I suspect a bug in the MapKit API.

See this link for information about someone else who is not working: http://www.iphonedevsdk.com/forum/iphone-sdk-development/19740-trigger-mkannotationview-callout-bubble.html#post110447

- edit -

Well, after it winds up a bit, here is what I was able to do:

 for (id<MKAnnotation> currentAnnotation in mapView.annotations) { if ([currentAnnotation isEqual:annotationToSelect]) { [mapView selectAnnotation:currentAnnotation animated:FALSE]; } } 

Note. This requires the implementation of - (BOOL)isEqual:(id)anObject for your class that implements the MKAnnation protocol.

+9
Aug 24 '09 at 2:10
source share

If you just want to open a callout for the last added annotation, try this, works for me.

[mapView selectAnnotation:[[mapView annotations] lastObject] animated:YES];

+6
Sep 10 '09 at 20:28
source share

I carefully read the API and finally found the problem:




If the specified annotation is not on-screen and therefore has no associated representation of the annotation, this method has no effect.

So, you can wait a while (for example, 3 seconds), and then perform this action. Then it works.

+5
Sep 11 '10 at 7:06
source share

The problem with calling selectAnnotation from - (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView is that, as the name implies, this event is fired only after your MapView loads initially, so you cannot call the annotation leader if you add it after MapView has finished loading.

The problem with calling it from - (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views is that your annotation may not appear on the screen when you selectAnnotation , which may lead to its invalidity. Even if you focus the MapView region on the coordinate of the annotation before adding the annotation, it takes a little delay to delay the region, which is necessary to trigger selectAnnotation before the annotation is visible on the screen, especially if you live setRegion .

Some people solved this problem by calling selectAnnotation after the delay itself:

 -(void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views { [self performSelector:@selector(selectLastAnnotation) withObject:nil afterDelay:1]; } -(void)selectLastAnnotation { [myMapView selectAnnotation: [[myMapView annotations] lastObject] animated:YES]; } 

But even then, you may get strange results, since it might take more than one second for the annotation for the annotation to appear on the screen depending on various factors, such as the distance between your previous MapView area and the new one or the speed of your Internet connection.

I decided to make a call from - (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated , because it ensures that the annotation is actually displayed on the screen (provided that you set the MapView area to the coordinate of the annotation), since this The event is fired after setRegion (and its animation) has finished. However, regionDidChangeAnimated triggered whenever the area of ​​your MapView changes, including when the user just rolls around the map, so you need to make sure that you have the condition to correctly identify when the right time is coming to trigger the annotation callout .

Here is how I did it:

 MKPointAnnotation *myAnnotationWithCallout; - (void)someMethod { MKPointAnnotation *myAnnotation = [[MKPointAnnotation alloc] init]; [myAnnotation setCoordinate: someCoordinate]; [myAnnotation setTitle: someTitle]; MKCoordinateRegion someRegion = MKCoordinateRegionMakeWithDistance (someCoordinate, zoomLevel, zoomLevel); myAnnotationWithCallout = myAnnotation; [myMapView setRegion: someRegion animated: YES]; [myMapView addAnnotation: myAnnotation]; } - (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated { if (myAnnotationWithCallout) { [mapView selectAnnotation: myAnnotationWithCallout animated:YES]; myAnnotationWithCallout = nil; } } 

Thus, your annotation is guaranteed to be displayed on the screen at the time of the call to selectAnnotation , and the if (myAnnotationWithCallout) does not guarantee that an area parameter other than that located in - (void)someMethod will cause a callout.

+4
01 Sep '13 at 2:29 on
source share

Due to something like the code shown by benvolioT, which I suspect exists on the system when I used the selectAnnotation: animation: method, it didn’t show callOut, I guessed that the reason was that it was already selected, and he avoided asking MapView to redraw callOut on the map using the annotation heading and subtitles.

So, the solution was simply to first deselect it and reselect.

E: First, I needed to do this in the Apple touchMoved method (i.e. how to drag and drop AnnotationView) to hide the callOut. (Just using annotation.canShowAnnotation = NO just doesn’t work, as I suspect that it needs to be redrawn. Deactivating Annnotaiton causes the necessary actions. In addition, refusing the choice did not do this trick, callOut disappeared only once and immediately redrawn. there was a hint that he was automatically re-elected).

 annotationView.canShowAnnotation = NO; [mapView deselectAnnotation:annotation animated:YES]; 

Then, simply using the code below, the touchEnded method did not return callOut (the annotation was automatically selected by the system by then and, apparently, the call was redrawn Out never occrrs):

 annotationView.canShowAnnotation = YES; [mapView selectAnnotation:annotation animated:YES]; 

Decision:

 annotationView.canShowAnnotation = YES; [mapView deselectAnnotation:annotation animated:YES]; [mapView selectAnnotation:annotation animated:YES]; 

It just bought callOut, presumably it re-initiated the callOut redraw process using mapView.

Strictly speaking, I have to determine whether the annotation is the current annotation or not (what I know is selected), and whether callOut really shows or not (which I don’t know) and decided to redraw it accordingly, this would be better. However, I have not yet found a method for detecting callOut and will try to do it myself, at this stage it is a bit superfluous.

+3
Jan 30 '10 at 6:30
source share

Steve's answer made me understand that selectAnnotation needs to be called from the mapViewDidFinishLoadingMap method. Sorry, I can’t vote, but I want to say thank you.

+1
Mar 16 '10 at 8:25
source share

Resetting annotations will also lead to the foreground.

  [mapView removeAnnotation: currentMarker]; [mapView addAnnotation:currentMarker]; 
0
Mar 31 '16 at 5:15
source share

Just add [mapView selectAnnotation: point animated: YES];

0
Feb 08 '17 at 6:38
source share



All Articles