iOS iPhone show user direction and orientation in space like the compass app on MKMapView

非 Y 不嫁゛ 提交于 2019-12-05 00:20:20


When the compass app uses a map view to display it's location, there's a little cone that displays the direction in which the phone is pointing. However, I was unable to reproduce it using MKMapView that shows user's location. Is this cone of sight feature available to developers, or will I have to implement one myself?

iPhone compass map app

Thank you!


I faced a similar situation. I don't think we have library or settings to display the direction on the blue icon (at least my search was not successful).

However it is not difficult to create our own direction indicator using the CLHeading (reference in TommyG's answer).

What I did was to display the blue icon as in the map and provide a small arrow in a different view to indicate the direction.

Hope this helps in some way


This is extremely easy like a piece of cake with MapKit. This is called UserTrackingMode. You have write down just one line of code to make the map become "compass-like":

 [mapView setUserTrackingMode:MKUserTrackingModeFollowWithHeading animated:YES];

In addition, there are about 3 type of UserTrackingMode:

- MKUserTrackingModeNone (free scrolling map)
- MKUserTrackingModeFollow (center the user's location)
- MKUserTrackingModeFollowWithHeading (center user's location and track user's heading (direction)).

If you're in one of 2 tracking (not free) mode, then you scroll the map out, the mode will be automatically change to free mode.


Here is the relevant framework that you can use for this matter:


MTLocation has a great bundle of images including the cone that you are after:


Suppose you have a temporary image called "imageTexture.jpg" saved in cache directory. The favorite one "FavoritePhoto.jpg" is saved in documents directory. To overwrite the favorite one in the documents directory you can do like this.

    NSError *errorDesc;

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *statesDescriptionPath = [documentsDirectory stringByAppendingPathComponent:@"FavoritePhoto.jpg"];

    NSFileManager *fileManager = [NSFileManager defaultManager];

    NSString *cacheDirectory = [NSFileManager getCacheDirectory];
    NSString *temporaryPath = [cacheDirectory stringByAppendingPathComponent:@"imageTexture.jpg"];

    NSURL *originalURL = [NSURL fileURLWithPath:statesDescriptionPath];
    [fileManager replaceItemAtURL:originalURL withItemAtURL:[NSURL fileURLWithPath:temporaryPath] backupItemName:nil options:NSFileManagerItemReplacementUsingNewMetadataOnly resultingItemURL:&originalURL error:&errorDesc];

    if (errorDesc)
        NSLog(@"there was an error overwriting the favorite photo: %@", errorDesc.description);

I am using a NSFileManager category to get the cache directory

Here is the code for NSFileManager+Powertools.h

#import <Foundation/Foundation.h>
@interface NSFileManager (Powertools)
+ (NSString *)getCacheDirectory;

Here you can see the code for NSFileManager+Powertools.m

#import "NSFileManager+Powertools.h"

@implementation NSFileManager (Powertools)

+ (NSString *)getCacheDirectory
    NSString *path = nil;
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
        if ([paths count])
            NSString *bundleName =
            [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"];
            path = [[paths objectAtIndex:0] stringByAppendingPathComponent:bundleName];
        return path;