1

I have this code:

// MapViewController.h
#import <Foundation/Foundation.h>
#import "MyCLController.h"
#import <MapKit/MapKit.h>

@class ShowsContainerController;

@interface MapViewController : UIViewController <MyCLControllerDelegate,MKMapViewDelegate> {
    MyCLController *locationController;
    MKMapView *mapView;
}

- (void)locationUpdate:(CLLocation *)location;
- (void)locationError:(NSError *)error;

@property (nonatomic, retain) IBOutlet MKMapView *mapView;
@property (assign) BOOL updateMap;
@property (strong) ShowsContainerController *parent;

@end

// MapViewController.m
#import "MapViewController.h"
#import "ShowsContainerController.h"

#define METERS_PER_MILE 1609.344

@implementation MapViewController

@synthesize parent, mapView;

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.updateMap = YES;
    locationController = [[MyCLController alloc] init];
    locationController.delegate = self;
    [locationController.locationManager startUpdatingLocation];
    mapView.delegate = self;
}

- (void)locationUpdate:(CLLocation *)location {

    if( self.updateMap ){
        MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(location.coordinate, 0.5*METERS_PER_MILE, 0.5*METERS_PER_MILE);

        [mapView setRegion:viewRegion animated:YES];

        self.parent = (ShowsContainerController *)self.parentViewController;

        [self.parent setLocation:location];

        self.updateMap = NO;
    }
}

- (void)locationError:(NSError *)error {
    NSLog([error localizedDescription]);
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    self.parent.mapReady = YES;

    if( self.parent.locationSet ){
        [self.parent callApi];
    }
}

#pragma mark MKMapViewDelegate

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
    NSLog(@"delegating user location");
    // if it's the user location, just return nil.
    if ([annotation isKindOfClass:[MKUserLocation class]])
        return nil;

    NSLog(@"delegating pins");
    static NSString* ShowAnnotationIdentifier = @"showAnnotationIdentifier";

    MKPinAnnotationView* pinView = (MKPinAnnotationView *)
    [mapView dequeueReusableAnnotationViewWithIdentifier:ShowAnnotationIdentifier];

    if (!pinView)
    {
        // if an existing pin view was not available, create one
        MKPinAnnotationView* customPinView = [[MKPinAnnotationView alloc]
                                              initWithAnnotation:annotation reuseIdentifier:ShowAnnotationIdentifier];
        customPinView.enabled = YES;
        customPinView.pinColor = MKPinAnnotationColorRed;
        customPinView.animatesDrop = YES;
        customPinView.canShowCallout = YES;

        return customPinView;
    }
    else
    {
        pinView.annotation = annotation;
    }
    return pinView;
}

#pragma mark -

@end

And here's the code adding my pins; it isn't fired until an api call is made, which is after viewDidAppear is fired:

- (void)placeAnnotations:(NSArray *)shows
{

    NSEnumerator *e = [shows objectEnumerator];
    id show;
    NSMutableArray *annotations = [[NSMutableArray alloc] init];

    while (show = [e nextObject]) {
        double lat = [[[[[show objectForKey:@"venue"] objectForKey:@"location"] objectForKey:@"geo:point"] objectForKey:@"geo:lat"] doubleValue];
        double lng = [[[[[show objectForKey:@"venue"] objectForKey:@"location"] objectForKey:@"geo:point"] objectForKey:@"geo:long"] doubleValue];

        ShowAnnotation *annotation = [[ShowAnnotation alloc]
                                      initWithCoordinate:CLLocationCoordinate2DMake(lat, lng)
                                      withMap:self.mapController.mapView
                                      withTitle:[show objectForKey:@"title"]
                                      withSubtitle:[[show objectForKey:@"venue"] objectForKey:@"name" ]];
        [annotations addObject:annotation];
    }

    NSLog(@"adding annotations");
    [self.mapController.mapView addAnnotations:annotations];

}

The log shows "delegating user location", but never "delegating pins". It doesn't even fire viewForAnnotation more than the one initial time for the user's location.

The delegation seems to be working, otherwise I wouldn't be able to capture this selector, but why is it firing for only the user location and not firing for subsequent annotation additions?

dclowd9901
  • 6,756
  • 9
  • 44
  • 63
  • The most obvious reason is that you simply have no other annotations than MKUserLocation one. Try logging going through placeAnnotations: with a breakpoint and see if it ever enters the while loop – Eugene Mar 17 '13 at 17:53
  • It does. They appear on the map, too, but without any of the properties set in viewForAnnotation. They don't animate and have no callout box, and I can't set their pin color. – dclowd9901 Mar 17 '13 at 18:03
  • Well there's no "delegating user location" in your viewForAnnotation: method. Are you sure you've properly set the delegate of a mapView? – Eugene Mar 17 '13 at 18:04
  • Apologies; I updated my code after I pasted it. Updated it in example now... – dclowd9901 Mar 17 '13 at 18:22
  • I'm pretty positive your code should work. The reason must be something small and obscured and it is not related to the two snippets of code you've posted. I'd rather search for a problem within mapController itself – Eugene Mar 17 '13 at 18:31
  • Hence why I posted it on here :) I honestly can't figure it out. I'll post the map controller too. – dclowd9901 Mar 17 '13 at 18:47
  • Added MapViewController header and implementations – dclowd9901 Mar 17 '13 at 18:52
  • Are you using `MyCLController` for the sole purpose of getting user location for the mapview? It can be done via delegate callback of mapview `- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation;`. Other than that I still struggle to see anything that's wrong with your code and there are more dependencies now with ShowsContainerController. I think you should use a good ol' step by step debugging starting from the point of the first location request, ending with viewForAnnotation. – Eugene Mar 17 '13 at 19:01
  • Figured it out: I was apparently (for whatever dumb reason) assigning another controller to the mapView.delegate. It was overwriting the delegate before the MapViewController had a chance to handle the subsequent calls for the pins. I feel like an idiot. Check those delegation assignments. – dclowd9901 Mar 17 '13 at 22:19

0 Answers0