I have custom markers in a map view. When the user touches one the app moves to another page. If the user returns to the map and touches the same item again
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
is not called until you touch somewhere in the map and then touch the marker again.
I tried deselecting the annotation view but the docs say not too, and in any case it didn't work.
Any ideas on how to fix this?
Instead of setting view.selected directly which the documentation says not to do, call the deselectAnnotation:animated: method instead:
[mapView deselectAnnotation:view.annotation animated:YES];
By the way, for the reverse, there's the selectAnnotation:animated: method.
Try using a UITapGestureRecognizer to recognize taps on the annotation view.
I have an app which searches using a Web service for informations about stations, then I get the response JSON. But each time I change the position of the center I have to reload the pins and add new ones, even if they are already on the map.
I can get the response JSON, get the information to display and create the annotations. The problem is when I move the center, it reloads the annotations over the others.
The problem is I was inserting that method in the method that makes the connection to the web service or when i receive the response...
But I inserted the method in this one in the first line:
- (MKAnnotationView *)mapView:(MKMapView *)mapViewStation viewForAnnotation:(id <MKAnnotation>)annotation
[map removeAnnotations:map.annotations];
//Code
It rocks. Thanks
I want to add multiple MKAnnotations with the callout showing. I searched a few different threads on S.O and could not find a way to do it. Has anyone figured out how to add multiple pins with the callout visible?
Ok!
You should use [mapView selectAnnotation:currentAnnotation animated:FALSE]
But be sure to place this in the - (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView
delegate method
Trigger MKAnnotationView callout
is there a way to update (i.e. moving around) a MKOverlay that is already added to the MKMapView. Removing a old one and adding a new one is terrible (slow).
i.e i would like to trigger the background function that is calling this function when an overlay moves on the screen:
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
(with MKAnnotions its a little better i think, but i cant use MKPolyline, MKPolygon, etc. and the whole information is reduced to a single point)
MKOverlayView has the following methods which force MapKit to re-render the given mapRect:
- (void)setNeedsDisplayInMapRect:(MKMapRect)mapRect
- (void)setNeedsDisplayInMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale
If you’re using a timer (or periodical HTTP request or some sort of other method for determining that your overlay should be updated), calling one of the above methods on the overlayView will cause it to re-render that spot on the map (i.e. -canDrawMapRect:zoomScale: will be called again, and then -drawMapRect:zoomScale:inContext: will be called if the former returns YES).
Update:
If you’re not sure what mapRect you need to re-render, you might be able to use the MKMapRectWorld constant as the mapRect — which I believe would cause the overlay across the entire map to reload (once visible).
Use MKAnnotations. You can change the coordinate of them. Just disable any touch-related stuff. You would need your own drawing code to draw the annotations, OpenGL would probably do the trick. Nobody would know the difference.
I actually had to force the overlay view to invalidate the path, to clear out the old path before setting up a new one. [polygonView invalidatePath]. Telling the map view that it needs a display refresh was insufficient for me.
This seems to force the map to refresh overlays. Probably annotations as well.
[self.mapView setCenterCoordinate:self.mapView.centerCoordinate];
Swift 3+ update, this worked for me, thanks #zenchemical for the inspiration.
DispatchQueue.main.async {
self.map.add(overlay, level: .aboveRoads)
self.map.setCenter(self.map.centerCoordinate, animated: false)
}
Side note, I can't help feeling that this shouldn't be necessary and there is a more appropriate solution, however, I haven't found it. Even though the add command is dispatched to the main queue, the overlay reproducibly does not render until I move the map.
there is a problem with raw setNeedsDisplay if the bounding rectangle of the polygon changes then MKMapView would not update whole rectangle correctly,and secondly,MKPolygon/MKPolygonRenderer's polygon is not updatable,and the problem with add/remove pipeline is if there is too much request to update the MapView it can get slower in the pipeline, I currently use a 30Hz thread loop if there is an update in polygon i do add/remove
I have been searching for this all night and I have just so frustrated. When a MKPinAnnotationView is clicked, the name and the subtitle comes up. I also want to center that point on the view. I figured there was some method I had to override because the information that pops up happened without me having to code it. Hopefully this was clear enough for you all.
And in the mean time, I feel like there is some hidden guide on this use of MKMaps and other classes. Either that or it is terribly documented because I am having a lot of trouble finding information. Thanks.
Have you tried overriding setSelected:animated:? (defined in MKAnnotationView)
-(void)mapView:(MKMapView *)mapView1 didSelectAnnotationView:(MKAnnotationView *)view{
}
This is the method that is called when you tap on a pin.