didAddAnnotationViews not working on MKMapView - objective-c

I've been playing around with the MKMapView and trying get my head around how the MKMapViewDelegate system works. So far I have no luck in getting the didAddAnnotationViews to get called when the current location marker is added.
I have set my app delegate to implement MKMapViewDelegate, I have an Outlet to the MapView in my xib and have set the delegate property of the MapView to be self, as in the app delegate instance. I have implemented didAddAnnotationViews in the app delegate which I simply NSLog any calls to it as shown below. The map is set to show current location which it does and adds the blue pin annotation on startup, but for some reason didAddAnnotationViews is not being hit.
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views{
NSLog(#"Annotation added!");
}
Any ideas what I might have missed?

I came across the same issue in BNR. Here is what I ended up using:
// Tell MKMapView to zoom to current location when found
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
NSLog(#"didUpdateUserLocation just got called!");
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance([userLocation coordinate], 250, 250);
[mapView setRegion:region animated:YES];
}

mapView:didAddAnnotations: is only called in response to addAnnotation: or addAnnotations:. The users location pin will not trigger this delegate method.

Just wanted to confirm that I was able to get this working using
- (void)mapView:(MKMapView *)mv didAddAnnotationViews:(NSArray *)views
{
MKAnnotationView *annotationView = [views objectAtIndex:0];
id <MKAnnotation> mp = [annotationView annotation];
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance([mp coordinate], 250,250);
[mv setRegion:region animated:YES];
}
Make sure you are using
mapView.delegate = self;
or
[mapView setDelegate:self];

Related

calloutAccessoryControlTapped not being called

I am trying to use the CalloutAccessory feature, but the delegate method never gets called. I have the delegate properly set up as other mapview delegate methods in my code are firing fine, but for some reason for this one, the delegate method never gets called when the button is tapped.
I have tried extending RouteViewAnnotation from both the MKAnnotationView and the MKPinAnnotationView, and it makes no difference.. the delegate method never gets called.
What am I missing? Do I need something else that isn't here for this to work? The RouteAnnotationView just overrides the drawrect, and has no other code in it.
Relevant Code:
In ViewForAnnotation
- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation{
if([annotation isMemberOfClass:[RouteAnnotation class]])
{
RouteAnnotationView *routeAnnotationView = [[RouteAnnotationView alloc] initWithFrame:(CGRectMake(0,0,100,50))] ;
[routeAnnotationView setBackgroundColor:[UIColor clearColor]];
routeAnnotationView.centerOffset = CGPointMake(0,-25);
routeAnnotationView.canShowCallout = TRUE;
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 100.0, 40.0)];
[button setTitle:#"Select" forState:UIControlStateNormal];
button.backgroundColor = [UIColor blueColor];
[routeAnnotationView setRightCalloutAccessoryView:button];
return routeAnnotationView;
}
.
.
.
}
In calloutAccssoryControlTapped
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
NSLog(#"CALLOUT BUTTON TOUCHED");
}
Okay, I figured it out... I had a tapGestureRecognizer assigned to the MapView (A WildcardGestureRecognizer (https://github.com/OrbJapan/ResizableMKCircleOverlay/blob/master/MapView/WildcardGestureRecognizer.m) to be exact) added to my MapView, and while this had not interfered in any way with annotation touches, or other touches in the MapView or MapView Delegate methods I was using, for some reason this completely interfered with the calloutAccessoryControlTapped Delegate method and it was never called... once I removed this the method called without issue.

Xcode6 IOS8 mapkit pins not showing

i wondering if someone may be able to help me. I am new to xcode and im trying to build a basic app. i have followed this tutorial
http://rshankar.com/how-to-add-annotation-to-mapview-in-ios/
i have copied the source code directly, i don't get any errors or warnings, however when running the app the pin locations do not show. Im not sure if they are there ( just invisible ) or whether they are not showing at all. I can't seem to find the issue.
Would anyone be able to suggest what the problem could be?
Thanks in advance.
actually managed to fix this, turns out the coordinates were round the wrong way!!!! Noob error!! I would like to change the callout on the pins if anyone could shed some light on where to change the code on the tutorial.
Thanks
To change the callout of the pins:
make the class that has your map view implement the <MKMapViewDelegate> protocol
set the delegate of your map view to that class (e.g. mapView.delegate = self;)
implement MKMapViewDelegate's (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation method in that class
something like this:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
// If it's the user location, just return nil
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
// Handle custom annotations
if ([annotation isKindOfClass:[NAME_OF_CLASS_IMPLEMENTING_MKANNOTATION_PROTOCOL class]])
{
// Try to dequeue an existing annotation view first
MKAnnotationView *annotationView = (MKAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:#"AnnotationViewIdentifier"];
if (!annotationView)
{
// If an existing pin view was not available, create one
annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"AnnotationViewIdentifier"];
annotationView.canShowCallout = YES;
// set callout
UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
annotationView.rightCalloutAccessoryView = rightButton;
}
else
{
annotationView.annotation = annotation;
}
return annotationView;
}
return nil;
}
On your map pins (which should be made from a class that implements the MKAnnotation protocol), you should be able to set the title and subtitle properties.

IOS 7 : didAddAnnotationViews not response to addAnnotation

I am trying to add annotations into my MKMapView and I want to set annotations to be clickable.(clickable feature I did in didAddAnnotationViews.)
Actually, this feature is working fine for IOS 6, but not working for IOS 7. I added a simple NSLog print statement in my didAddAnnotationViews method, and I found didAddAnnotationViews not response to addAnnotaion properly. I thought didAddAnnotationViews will be called each time in response to addAnnotaion . When I added several annotations only one log statement print, which means didAddAnnotationViews only execute once I think.
I'm using MapKit, MKMapView and this issue only occur in IOS 7. Can anyone give me a idea how to fix or find the reason why didAddAnnotationViews not working properly?
- (void)mapView:(MKMapView *)mv didAddAnnotationViews:(NSArray *)views
{
MKAnnotationView *annotationView = [views objectAtIndex:0];
MapViewAnnotation *annotation=annotationView.annotation;
NSLog(#"<==========didAddAnnotationViews=============> %#",annotation.title);
annotationView.canShowCallout=YES;
if(annotation.subtitle==nil){
annotationView.rightCalloutAccessoryView = nil;
}else{
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(annotation.coordinate, 11000, 11000);
[mv setRegion:region animated:YES];
}
}
The method signature implies that multiple annotation views are given at the same time:
- (void)mapView:(MKMapView *)mv didAddAnnotationViews:(NSArray *)views;
Try logging the array of views with:
NSLog(#"%#", views);
If you are lucky, you'll see all your annotations. Iterate over them instead of only looking at the first object at index 0.

Implementing MKMapView didRemoveAnnotationViews method?

There's a method of MKMapViewDelegate protocol:
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views
Which I'm using for custom pin dropping animations, though there's no method for "remove" (didRemoveAnnotationViews) action to implement custom animations when annotation views are being removed.
Has anyone figured out a workaround for that?
Thanks!
[mapview deselectAnnotation:[mapview.selectedAnnotations objectAtIndex:0] animated:YES];
or
[mapview deselectAnnotation:calloutMapAnnotationView.annotation animated:YES];
where calloutMapAnnotationView is the callout bubble object of selected custm pin.

ViewForAnnotation is not being called

I am trying to make a map, where I can see my current location, and see what the street is called.
so far, I am able to put a pin on my map, but for some reason, I am not getting the callout.
and I have put a NSLog in my viewForAnnotation method, but it is not being called, so i wasn't able to test it.
can someone help me?
-(void)lat:(float)lat lon:(float)lon
{
CLLocationCoordinate2D location;
location.latitude = lat;
location.longitude = lon;
NSLog(#"Latitude: %f, Longitude: %f",location.latitude, location.longitude);
//One location is obtained.. just zoom to that location
MKCoordinateRegion region;
region.center=location;
//Set Zoom level using Span
MKCoordinateSpan span;
span.latitudeDelta=.005f;
span.longitudeDelta=.005f;
region.span=span;
[map setRegion:region animated:TRUE];
//MKReverseGeocoder *geocoder=[[MKReverseGeocoder alloc] initWithCoordinate:location];
//geocoder.delegate=self;
//[geocoder start];
if (cPlacemark != nil) {
[map removeAnnotation:cPlacemark];
}
cPlacemark=[[CustomPlacemark alloc] initWithCoordinate:location];
cPlacemark.title = mPlacemark.thoroughfare;
cPlacemark.subtitle = mPlacemark.locality;
[map addAnnotation:cPlacemark];
[cPlacemark release];
[mLocationManager stopUpdatingLocation];
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
// try to dequeue an existing pin view first
if ([annotation isKindOfClass:[CustomPlacemark class]]){
MKPinAnnotationView *pinView=(MKPinAnnotationView *)[map dequeueReusableAnnotationViewWithIdentifier:#"customIdentifier"];
if (!pinView)
{
// if an existing pin view was not available, create one
MKPinAnnotationView* cPinAnnoView = [[[MKPinAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:#"customIdentifier"] autorelease];
cPinAnnoView.pinColor = MKPinAnnotationColorPurple;
cPinAnnoView.animatesDrop = YES;
cPinAnnoView.canShowCallout = YES;
// Add button
UIButton *leftButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[leftButton addTarget:self action:#selector(annotationViewClick:) forControlEvents:UIControlEventTouchUpInside];
cPinAnnoView.leftCalloutAccessoryView = leftButton;
} else
{
pinView.annotation = annotation;
}
return pinView;
}
return nil;
}
Right now I have customized my viewForAnnotation to be like this.
But I still can't get a callout from my pin and the pin remains red.
But it should be purple of nothing at all
I had the same problem which was not setting the MapView delegate to the File Owner.
Open your nib
Right click on the MapView
Drag the delegate to the File's Owner
I had the same problem, as you mentioned. The delegate had been set to ViewController, but the viewForAnnotation selector was not being called. After some checks, I realized if you do not call addAnotation in the main thread, mapView would not call viewForAnnotation, so following update resolved my problem:
Before:
[_mMapView addAnnotation:marker];
After:
dispatch_async(dispatch_get_main_queue(), ^{
[_mMapView addAnnotation:marker];
});
In order to get the viewForAnnotation to be called, add mapView.delegate=self; to e.g. the viewDidLoad method:
- (void)viewDidLoad {
[super viewDidLoad];
mapView.delegate=self;
}
Could it be that your annotation has been added outside the current view area of the MKMapView?
For storyboard, Ctl drag the MKMapView to the orange circle on the bottom bar of ViewController, and select delegate.
This will solve the problem.
As vatrif mentioned in the comments, you must set your delegate BEFORE adding annotations to your MKMapView object.
Others have already explained, odds are high you have not connected your mapview delegate to your controller. Its the first thing to check
i have been working in ios 9 Mapview related app and I experienced the same problem.
somehow I solved my problem, in my case im resizing the mapview.
I added delegate after i resize the mapview. it works now perfectly.!
After having set the delegate for the mapview if still the viewforannotation not getting called then this is something which you have missed - set the self.mapView.showsUserLocation to YES, in interface builder you can tick the shows userLocation option in attributes inspector.