How to make an iPhone App – Part 5: The Accelerometer

By
On November 1, 2010

Yes, your iPhone has an accelerometer. I know this is not a physics class but the best way to define it is saying that it is a device to detect the magnitude and direction of acceleration. iDevices uses it to detect rotation, shake gestures, among others.

To get started we are going open Xcode and go to File->New Project, in iPhone OS select Application and in the icons of the right double click “View-based Application”. Nothing new.

I’m calling my project “Accelerometer”, you can give it the name you want.

Reading Accelerometer Data

There are three accelerometers in the iPhone, one for each axis. The X-axis reads from left to right, the Y-axis running up and down and the Z-axis for acceleration from back to front.

To read this data you need to call the object UIAccelerometer, you don’t have yo create it nor destroy it, just use it. It contains all the information you need from the accelerometer. Lets create an interface to display this data.

Double click the AccelerometerViewController.xib in the resources folder and drag to the view three labels and a round rect button.

Double click and erase the text of the labels, then save and return to Xcode.

Now we have to create the code for the labels. Click on AccelerometerViewController.h in the “Clases folder”. Right before the opening curly brace of the @interface add to let it know we are going to use the accelerometer data in this view, then declare the three atributes of the class to appear in the labels, like this:

@interface AccelerometerViewController : UIViewController

{
	UILabel *x;
	UILabel *y;
	UILabel *z;
}
@property (nonatomic, retain) IBOutlet UILabel *x;
@property (nonatomic, retain) IBOutlet UILabel *y;
@property (nonatomic, retain) IBOutlet UILabel *z;
@end

We are done here. Go to the implementation (AccelerometerViewController.m). First of all don’t forget to @synthesize x, y, z;. Then find the method “viewDidLoad” and uncomment it. Before the [super viewDidLoad] statement create an object and assign it the [UIAccelerometer sharedAccelerometer], with this we are creating a reference to the accelerometer data. Then set the accelerometer delegate to the view and the update interval for the values to ten times per second. The method should look like this:

- (void)viewDidLoad {

	UIAccelerometer *accel = [UIAccelerometer sharedAccelerometer];
	accel.delegate = self;
	accel.updateInterval = 1.0f/10.0f;

    [super viewDidLoad];
}

At this point we have prepared the view to take the data from the accelerometer. Now we need to really take it. There is a method called “accelerometer didAccelerate”. This will allow us to read the data and display it in the labels:

- (void)accelerometer:(UIAccelerometer *)accelerometer
		didAccelerate:(UIAcceleration *)acceleration
{
	x.text = [NSString stringWithFormat:@"X is: %f", acceleration.x];
	y.text = [NSString stringWithFormat:@"Y is: %f", acceleration.y];
	z.text = [NSString stringWithFormat:@"Z is: %f", acceleration.z];
}

The code is ready, the only thing left is to connect the variables to the interface.

Now let’s build and run. The iPhone simulator will show up and your app will run, it may look like you did something wrong because the data is not appearing, well, the problem is that the simulator has no accelerometer, to test your app you need to deploy it to a real device, and in order to do so you need to pay at least $99.

But there is one thing the simulator can do, simulate rotation to landscape.

Switching to Landscape Mode

You may be wondering what was the round rect button for. I created it to demonstrate this part of the tutorial. If you build and run the app we just created and you press command+left or righr arrow, the iPhone will switch to landscape mode, the problem is that our app wont.

Go to the “AccelerometerViewController.m” and find the method “shouldAutorotateToInterfaceOrientation” and uncomment it. Here we say what orientations our app will support. Replace the method with this one:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {

    if (interfaceOrientation == UIInterfaceOrientationPortrait ||
		interfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
		interfaceOrientation == UIInterfaceOrientationLandscapeRight)
		return YES;
	else {
		return NO;
	}

}

With this we support rotation to landscape left and right. If you build and run you’ll se that the view now is switching to landscape mode but it isn’t adjusting very well to the new size of the window.

One way to solve it is to create a new view and switch to that when the iPhone rotates. The other way is to change a few properties in the inspector window of interface builder, the problem is that it doesn’t work for all the cases, sometimes you have to take the first option. In our case the second option works.

Double click the “AccelerometerViewController.xib” in the resources folder to open interface builder. Click the rounded button and select the “Size” tab of the Inspector Window. In the section for “Autosizing” you’ll notice there is a square with two red lines perpendicular to the left side and the upper side. This means that the button is linked to left and the top of the view to maintain that distance to that sides.

Click the left side to uncheck it and select the right side. Now if you save and build and run the button should stick to the left.

There are other properties, like resizing. If you click the horizontal arrow inside the square and the line in the left outside the square, the button will resize maintaining a proportion.

it will look like this:

Conclusion

The only way to master this is practicing. Make more iPhone apps and make them rotate.

Stay tuned because we are getting closer to the end. The next stop is saving data.