Apple’s shake-detection algorithm analyses eight to ten successive
pairs of raw accelerometer triplet values and determines the angle between
these readings. If the change in angular velocity between successive data
points is large then the algorithm determines that a UIEventSubtypeMotionShake
has occurred, and the
motionBegan:withEvent:
delegate method
is called. Conversely, if the change in angular velocity is small and a
shake event has been triggered, the motionEnded:withEvent:
delegate method is
called.
Note
The iPhone is better at detecting side-to-side rather than front-to-back or up-and-down motions. Take this into account in the design of your application.
There are three motion delegate methods, mirroring the methods for
gesture handling: motionBegin:withEvent:
, motionEnded:withEvent:
and motionCancelled:withEvent:
. The first indicates
the start of a motion event, the second the end of this event. You cannot
generate a new motion event for a second (or two) following the first
event. The final delegate method is called when a motion is interrupted by
a system event, such as an incoming phone call.
Let’s go ahead and add shake detection to our Accelerometer
application. You’ll need to add another UILabel
to the UI that will change depending on
the motion event status. Click on the AccelerometerViewController.h interface file to
open it in the Standard Editor and add another UILabel
marked as an IBOutlet
to the class definition:
@interface AccelerometerViewController : UIViewController <UIAccelerometerDelegate> {
IBOutlet UILabel *xLabel;
IBOutlet UILabel *yLabel;
IBOutlet UILabel *zLabel;
IBOutlet UIProgressView *xBar;
IBOutlet UIProgressView *yBar;
IBOutlet UIProgressView *zBar;
IBOutlet UILabel *orientationLabel;
IBOutlet UILabel *shakeLabel;
IBOutlet UIImageView *arrowImage;
UIAccelerometer *accelerometer;
}
Save your changes and click on the AccelerometerViewController.m implementation file to open it in the Xcode editor.
The easiest way to ensure that the view controller receives motion
events is to promote it to First Responder in the viewDidAppear:
method. Remember to make the
controller resign as first responder when the view goes away. Add the
viewDidAppear:
method and modify the
existing viewWillDisappear:
method as
highlighted below. Use the canBecomeFirstResponder
method to indicate that the view controller can indeed become the First
Responder:
- (BOOL)canBecomeFirstResponder { return YES; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [self becomeFirstResponder]; } -(void) viewWillDisappear: (BOOL) animated{ [super viewWillDisappear:animated]; [[NSNotificationCenter defaultCenter] removeObserver: self]; [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; [self resignFirstResponder]; }
Save your changes and click on the AccelerometerViewController.xib file for the
last time. Drag-and-drop a UILabel
into
the View from the Object Library and connect it to the shakeLabel
outlet as in Figure 4-11.
Save your changes and return to the AccelerometerViewController.m file in the editor, and add the following delegate methods to the implementation:
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event { if ( motion == UIEventSubtypeMotionShake ) { shakeLabel.text = @"SHAKE"; shakeLabel.textColor = [UIColor redColor]; } return; } - (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event { if ( motion == UIEventSubtypeMotionShake ) { shakeLabel.text = @"NO SHAKE"; shakeLabel.textColor = [UIColor greenColor]; } return; } - (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event { if ( motion == UIEventSubtypeMotionShake ) { shakeLabel.text = @"SHAKE CANCELLED"; shakeLabel.textColor = [UIColor blackColor]; } return; }
Save your changes and click on the Run button in the Xcode toolbar. After the application is built and deployed to your device, try shaking the phone. You should see something very much like Figure 4-12.
Get Basic Sensors in iOS now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.