In my app i have a MapView and one annotation. The first touch on the pin showing it's view, but i can't find the to remove/hide it on another touch.
Thanks
Removes the specified annotation object from the map view.
- (void)removeAnnotation:(id < MKAnnotation >)annotation
Parameters
annotation:
The annotation object to remove. This object must conform to the MKAnnotation protocol.
To remove annotation view only check this question
[mapView deselectAnnotation:[mapView.selectedAnnotations objectAtIndex:0] animated:YES];
Related
I have a MKMapView with lots of annotations. When I tap on an annotation, the contact details(ABPersonViewController) of the annotation is pushed. In this class I have an option to delete the contact. As the contact is deleted from the addressbook, at the same time I need to remove the annotation from the mapview too.
As the delete button is tapped, the contact is removed from the addressbook, and the ABPersonViewController class is popped from the navigation stack. Now the user sees the mapview. But it should be without the annotation(contact) which was removed.
How can I do this.
Get the annotations from the mapview using the annotation property. Then iterate through the annotation list to get the particular annotation then use the
- (void)removeAnnotation:(id < MKAnnotation >)annotation
method to remove the annotation. I hope it will take care of your problem.
Add all the annotations in a mutable array and their corresponding address with it like:
NSMutablearray *array;
[array add object:[NSDictionary dictionarywithobjectandkeys:#"your object and keys"];
Now when the user deletes the address its subsequent annotation will also be deleted. That should do it.
For deleting all annotation use the code below;
[mapView removeAnnotations:mapView.annotations]
I have an MKMapView with several overlays. Works all just fine, and it's incredible how simple it works. There is, however, one thing I can't get to work. The idea is simple: when a user taps within the area that is covered by an overlay, a callout with some information about that overlay has to come up. The overlays are all MKPolygons, which follow the MKOverlay protocol and therefore the MKAnnotation protocol.
The MKOverlay protocol conforms to the
MKAnnotation protocol. As a result,
all overlay objects are also
annotation objects and can be
treated as one or both in your code.
If you opt to treat an overlay object
as both, you are responsible for
managing that object in two places. If
you want to display both an overlay
view and annotation view for it, you
must implement both the
mapView:viewForOverlay: and
mapView:viewForAnnotation: methods in
your application delegate. It also
means that you must add and remove the
object from both the overlays and
annotations arrays of your map.
This comes from the Apple docs. I tried something like this:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
MKAnnotationView *aView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:nil];
aView.canShowCallout = YES;
}
But that doesn't seem to work. I've tried using gesture recognizers, but I have no idea how to show a callout other than by using the canShowCallOut property...
I suppose you have to add the MKOverlays as annotations also
[self.mapView addAnnotations:myOverlays];
Then return a MKAnnotationView in (mapView:viewForAnnotation) that's not hidden, either a graphic (tap-able) or zero alpha view. Next, add a UITapGestureRecognizer for each MKOverlayView, make sure it works with the map's gestures (UIGestureRecognizerDelegate implementation for simultaneous recognition). Finally when your gesture recognizer fires do this
[self.mapView setSelectedAnnotations:[NSArray arrayWithObject:myOverlayView.overlay]];
I'm not certain that this actually triggers the callOut showing though.
Also make sure your return title and/or subtitle from your overlay object.
I want to detect tap on annotation pin(of mapkit) so that I can perform action on that event.
Now the default annotation flag pops up in case I touch the annotation pin. I want to customise that to call my method when pin is touched.
You need to implement the following delegate method
(MKAnnotationView) mapView viewForAnnotation:(id) annotation
Then just declare following in this method
MKPinAnnotationView *view=[[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:#"abc"];
view.canShowCallout=YES;
view.calloutOffset=CGPointMake(-20,10); //As per your choice
Then you can add UI to your callout eg UIButton or UIImage as
view.rightCalloutAccesoryView
View.leftCalloutAccesoryView
As pin on map is MKAnnotationView you can add UITapGestureRecognizer on it(of yours), but if it already has some GestureRecognizer than you will need to remove it first.
Thanks
How to show callout bubble without the user tapping on the pin ??
(Assuming you're talking about annotations on MKMapView)
Call [mapView selectAnnotation:yourAnnotation animated:YES]; with your annotation object
It can be done as Vladimir said, but I think you need to do it after the MKAnnotationView related to your annotation is shown.
You can use the method below (which is a method defined in MKMapViewDelegate) to get informed when an annotation view is added to your MKMapView:
-(void) mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views
So, basically you need to invoke the method mentioned by Vladimir
[mapView selectAnnotation:yourAnnotation animated:YES];
in the implementation of the delegate method I mentioned above
Is it possible to open simultaneously more then one callout?
The code:
- (void)mapViewDidFinishLoadingMap:(MKMapView *)theMapView {
for (id<MKAnnotation> currentAnnotation in theMapView.annotations) {
[theMapView selectAnnotation:currentAnnotation animated:YES];
}
}
opens only one callout.
Note that there is a method on MKMapView (not MKAnnotationView) for selecting an annotation programmatically that works more or less as you would expect:
- (void)selectAnnotation:(id < MKAnnotation >)annotation animated:(BOOL)animated
However, it automatically deselects any currently annotation at the same time so this doesn't solve your problem.
Oddly, there is a property on MKMapView that appears to hold an array of currently selected annotations:
#property(nonatomic, copy) NSArray *selectedAnnotations
But the documentation on this method says:
"Assigning a new array to this property
selects the first annotation in the
array only."
Just thought this might be of interest.
From a strict API perspective, this does not seem possible.
The -(void)setSelected:(BOOL)selected animated:(BOOL)animated selector on MKAnnotationView states : "You should not call this method directly. An MKMapView object calls this method in response to user interactions with the annotation." so the underlying message is that the selection of annotationView instances in under the full responsability of user selection, and as the user can only select one of them at a time, you shouldn't be able to get several of them selected at the same time.
Even if the documentation says that should not call this method directly, did you try to invoke it anyway with setSelected:YES on several MKAnnotationView instances to see what it gives ?
THE CLEAN WAY I WOULD DO IT : (not tested myself however)
don't rely on the selection mechanism of the MKMapView
subclass the MKAnnotationView to implement a custom one
do the customization in such a way that the callout is part of the annotation view so that you can display several of them.
If you do it like this, you can make appear several callout bubble at the same time and get something that would look like :
alt text http://a1.phobos.apple.com/us/r1000/048/Purple/2b/b2/ec/mzl.ttcsrlee.480x480-75.jpg
Since iOS 11, Apple added new annotation view called MKMarkerAnnotationView.
In func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?, when you dequeue the annotation view, make sure you cast it as MKMarkerAnnotationView (e.g. var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKMarkerAnnotationView), and set view's attributes titleVisibility and subtitleVisibility to .visible.