How to create a compass in iPhone

A Happy New Year! I hope everyone enjoy this winter season. I want you to remember another new year holiday, which is in Chinese calendar, coming in a few weeks. We will update our Chinese Astrology and Feng Shui App with a bunch of features, such as a compass to show direction on the screen. According to our partner, Eco-Med LLC which is Feng Shui guru company, ancient Chinese people have developed complex schema to determine the layout of rooms / furnitures depend on your “lucky” direction. In 21st century, the iPhone in your pocket contains a small device, it’s called magnetrometer, helps you to solve the difficult puzzle in a quick and easy way. In this article, I would like to explain the simplest method to implement a compass in your app. This tutorial contains following items:

Step 1: Create a project (e.g. CompassExample) and include frameworks


Step 2: In .h file, create Location Manager Object

CLLocationManager *locationManager;

Implement delegate

Next, add parameter

@property (nonatomic,retain) CLLocationManager *locationManager;

… don’t forget to synthesize it in .m file.

@synthesize locationManager;

Step 3: In .h file, create UIImageView and add reference in Interface Builder

IBOutlet UIImageView *compassImage;

Download Image from here Step 4: In .m file’s viewDidLoad function, initialize the location manager.

	locationManager=[[CLLocationManager alloc] init];
	locationManager.desiredAccuracy = kCLLocationAccuracyBest;
	locationManager.headingFilter = 1;
	[locationManager startUpdatingHeading];

Step 5: In .m file, implement delegate function.

First, you need to convert degree (e.g 360) to radian (e.g 3.14=2PI). Second, multiply -1 in order to rotate opposite direction that you twist your phone. Third, apply rotation with core animation function. In this example, I’m rotating from the current value to the new value. The duration is 0.5 second as you see below.

- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading{
	// Convert Degree to Radian and move the needle
	float oldRad =  -manager.heading.trueHeading * M_PI / 180.0f;
	float newRad =  -newHeading.trueHeading * M_PI / 180.0f;		
	CABasicAnimation *theAnimation;
	theAnimation=[CABasicAnimation animationWithKeyPath:@"transform.rotation"];
	theAnimation.fromValue = [NSNumber numberWithFloat:oldRad];
	theAnimation.toValue=[NSNumber numberWithFloat:newRad];
	theAnimation.duration = 0.5f;    
	[compassImage.layer addAnimation:theAnimation forKey:@"animateMyRotation"];
	compassImage.transform = CGAffineTransformMakeRotation(newRad);
	NSLog(@"%f (%f) => %f (%f)", manager.heading.trueHeading, oldRad, newHeading.trueHeading, newRad);	

That’s it! Of course, you have to deploy the app on your device to check the direction.

Source Code:

By: kiichi on: