Search code examples
iosuitabbarcontrollermapkitbreadcrumbsmkoverlay

MKOverlay route working in Apple Breadcrumb iOS code but not in my app


I am working on an iOS application and want to include the Breadcrumb iOS Mapkit route functionality provided by apple as one of the feature. I have created a UIViewController in the storyboard (as a tab from a tab bar controller) and inserted a MKMapView in it. I have also connected it to the outlet in ThirdViewController shown below. The classes are shown below. I have classes CrumbPath and CrumbPathView exactly as in the Breadcrumb example at http://developer.apple.com/library/ios/#samplecode/Breadcrumb/Introduction/Intro.html

Even with the same code, the mkoverlay route does not show in my app. Am I missing something important here. I am not experienced in iOS programming and may have missed something basic.

ThirdViewController.h

#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>

#import "CrumbPath.h"
#import "CrumbPathView.h"

@interface ThirdViewController : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate>
{

@private
    MKMapView *map;

    CrumbPath *crumbs;
    CrumbPathView *crumbView;

    CLLocationManager *locationManager;

}

@property (nonatomic, retain) IBOutlet MKMapView *map;
@property (nonatomic, retain) CLLocationManager *locationManager;
@end

ThirdViewController.m

#import "ThirdViewController.h"

@interface ThirdViewController ()
@end

@implementation ThirdViewController

@synthesize locationManager, map;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
// Do any additional setup after loading the view.

    self.wantsFullScreenLayout = YES;

    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;

    self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;

    [self.locationManager startUpdatingLocation];

    [self.view addSubview:self.map];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.

    self.map = nil;
    self.locationManager.delegate = nil;
    self.locationManager = nil;
}

-(void) dealloc
{

}

- (BOOL)shouldAutorotateToInterfaceOrientation (UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark -
#pragma mark MapKit

- (void) locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
    if(newLocation)
    {
        if((oldLocation.coordinate.latitude != newLocation.coordinate.latitude) && (oldLocation.coordinate.longitude != newLocation.coordinate.longitude))
        {
            if(!crumbs)
            {
                crumbs = [[CrumbPath alloc] initWithCenterCoordinate:newLocation.coordinate];
                [map addOverlay:crumbs];

                MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(newLocation.coordinate, 2000, 2000);
                [map setRegion:region animated:YES];
            }
            else
            {
                MKMapRect updateRect = [crumbs addCoordinate:newLocation.coordinate];

                if(!MKMapRectIsNull(updateRect))
                {
                    MKZoomScale currentZoomScale = (CGFloat)(map.bounds.size.width/map.visibleMapRect.size.width);

                    CGFloat lineWidth = MKRoadWidthAtZoomScale(currentZoomScale);
                    updateRect = MKMapRectInset(updateRect, -lineWidth, -lineWidth);

                    [crumbView setNeedsDisplayInMapRect:updateRect];
                }
            }
        }
    }
}

- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay
{
    if(!crumbView)
    {
        crumbView = [[CrumbPathView alloc] initWithOverlay:overlay];
    }
    return crumbView;
}
@end

Solution

  • You didn't have your ThirdViewController set as the delegate to your MKMapView in your storyboard, so mapView:viewForOverlay: was never being called. Setting the delegate property fixes the problem.