tags:

views:

6616

answers:

9

I'm working on a MKMapView with the usual colored pin as the location points. I would like to be able to have the callout displayed without touching the pin.

How should I do that? Calling "setSelected:YES" on the annotationview did nothing. I'm thinking of simulate a touch on the pin but I'm not sure how to go about it.

A: 

You'll probably have better luck asking 3.0 questions over in the iPhone dev forums... sorry, hopefully just few more days until the NDA on 3.0 development lifts.

P.S. - look at the map view methods...

Kendall Helmstetter Gelner
Thanks! That helped.
Seymour Cakes
NDA is lifted. This answer doesn't help anyone.
bentford
Unfortunately, since it's the accepted answer I can't delete it. I can't even downvote my own answer!
Kendall Helmstetter Gelner
+3  A: 

Ok, here's there solution to this problem.

To display the callout use MKMapView#selectAnnotation:animated method.

Seymour Cakes
This doesn't help. I can call this and it won't always animate the selection. The first time, yes. Every time after that, no - even if the method is called.benvolioT's solution also doesn't work for me. Even if I call selectAnnotation:animated: directly, when the annotation is known, doesn't work. Same issues as before. :(
Joe D'Andrea
+5  A: 

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

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

--edit--

Okay after screwing with this for a while, here is what I've been able to make work:

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

Note, this requires implementing - (BOOL)isEqual:(id)anObject for your class that implements the MKAnnotation protocol.

benvolioT
based on this I got [mapView selectAnnotation:[mapView.annotations objectAtIndex:0] animated:false]; to work to pick the first annotation.
Andiih
+2  A: 

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

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

+11  A: 

But there is a catch to get benvolioT's solution to work, the 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 the various methods like viewWillAppear, viewDidAppear of UIViewController and the - (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView is called is different between the first time the map is loaded with one particular location and the subsequent times the map is displayed with the same location. This is a bit tricky.

Steve Shi
Nothing tricky. Just needed to know to call: [mapView selectAnnotation] rather than [annotation setSelected].Thanks!
bentford
+1  A: 

Due to something like the code shown by benvolioT, that I suspect exists in the system, when I used selectAnnotation:animation: method, it did not show the callOut, I guessed that the reason was because it was already selected and it was avoiding from asking the MapView to redraw the callOut on the map using the annotation title and subtitle.

So, the solution was simply to deselect it first and to re-select it.

E.g: First, I needed to do this in Apple's touchMoved method (i.e. how to drag an AnnotationView) to hide the callOut. (Simply using annotation.canShowAnnotation = NO alone does not work, since I suspect that it needs redrawing. The deselectAnnotaiton causes the necessary action. Also, deselecting alone did not do that trick, the callOut disappeared only once and got redrawn straight away. This was the hint that it got reselected automatically).

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

Then, simply using the code below in touchEnded method did not bring back the callOut (The annotation has been automatically selected by the system by that time, and presumably the redrawing of the callOut never occrrs):

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

The solution was:

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

This simply bought back the callOut, presumably it re-initiated the process of redrawing the callOut by the mapView.

Strictly speaking, I should detect whether the annotation is the current annotation or not (selected, which I know it is) and whether the callOut is actually showing or not (which I don't know) and decide to redraw it accordingly, that would be better. I, however, have not found the callOut detection method yet and trying to do so myself is just a little bit unnecessary at this stage.

Yoichi
+1  A: 

Steve Shi's response made it clear to me that selectAnnotation has to be called from mapViewDidFinishLoadingMap method. Unfortunately i cannot vote up but i want to say thanks here.

kudor gyozo
A: 

I read the API carefully and finally I found the problem:


If the specified annotation is not onscreen, and therefore does not have an associated annotation view, this method has no effect.

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