Accelerometer

advertisement
The Accelerometer
CSE 391 Fall 2011
Tony Scarlatos
The Three Axes on the iPhone
Example Values: Portrait
X = 0.0
Z = 0.0
Y = - 1.0 (gravity)
Example Values: Landscape Right
X = 1.0 (negative if landscape left)
Y = 0.0
Z = 0.0
Example Values: Tilt 45 degrees X & Y
X = 0.5
Z = 0.0
Y = - 0.5
Example Values: Tilt 45 degrees Y & Z
X = 0.0
Z = - 0.5
Y = - 0.5
Uses for accelerometer values
• Detect orientation change
– Ex. Portrait to Landscape
• Detect a “Shake”
– Often used to clear fields or undo an action
• Use the Accelerometer as a control
– Commonly used in games
Detecting and Managing Orientation
• If you want your interface to adapt to different
orientations, such as rotating from portrait to
landscape, you’ll have to edit the
shouldAutorotateToInterfaceOrientation method in
your view controller to be specific about which
orientations you want to support.
• In the code that follows on the next slide, the
supported orientations are Portrait, LandscapeLeft
and LandscapeRight.
• In the simulator you can change orientations from
the Hardware drop down menu.
The shouldAutorotateToInterfaceOrientation
method
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrien
tation {
// Return YES for supported orientations
if (interfaceOrientation == UIInterfaceOrientationPortrait ||
//two vertical lines denote an OR statement
interfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
interfaceOrientation == UIInterfaceOrientationLandscapeRight)
return YES;
else {
return NO;
}
}
Locking out an orientation
It seems like this is a good place to remind you of the code we used to force the app into landscape mode in an
earlier demo:
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
if
((interfaceOrientation==UIInterfaceOrientationPortrait)||(interfaceOrientation==UIInterfaceOrientationPort
raitUpsideDown))
// NO locks out the portrait mode of the iPhone. The initial landscape orientation is also set in the summary
panel for the app target.
{
return NO;
}
if
((interfaceOrientation==UIInterfaceOrientationLandscapeLeft)||(interfaceOrientation==UIInterfaceOrientat
ionLandscapeRight))
{
return YES;
}
}
Interface Builder Autosizing Panel
If you want to compensate for the changes to
your interface because of supporting multiple
orientations, you can select those UI elements
in IB, and in the Autosizing tab of the
Inspector panel you can adjust their
properties. You can choose which sides of the
frame you want anchor the element to
(struts), or if you want the element to stretch
to fit the new orientation (springs).
Interface Builder Autosizing Panel
Origin establishes
the location of the
element in the view
Fields for entering discrete
values for size and position
of the UI element
STRUTS connect
The UI element to
the sides of the view
(upper left corner is the
default)
The preview window
shows the effects of your
changes to the UI element
SPRINGS stretch
The UI element to
the sides of the view
Detecting a Motion Event (Shake)
• The first thing to do to detect a motion event is to declare that
the view controller can be the first responder.
• The next thing to do is activate that status using the
viewDidAppear method.
• Then you can respond to either the motionBegan or
motionEnded methods (or both).
• You can test the event in the simulator in the Hardware drop
down menu which simulates a shake event.
• The code is written in the implementation file of the view
controller, and it simply changes the background color of the
view when the phone is shaken. It follows on the next slide.
The Shake Event
-
(BOOL)canBecomeFirstResponder {
return YES;
}
-
(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self becomeFirstResponder];
}
-
(void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event {
if (event.subtype == UIEventSubtypeMotionShake) {
self.view.backgroundColor = [UIColor redColor];
}
}
Accessing Accelerometer data
• The UIAccelerometer object contains the combined data from the 3
sensors (axes) on the iPhone.
• It is a “singleton” object – it always exists. You don’t have to create
or release it, you just need to request it.
• The method used to access the data is sharedAccelerometer.
Typically you set the delegate of the object to your view controller
(self).
• The other thing that you will need to set is the sampling rate using
the updateInterval method. A typical sampling rate is 30 times per
second.
• You can then use the data in your app by employing the
didAccelerate method.
• In the code that follows on the next 3 slides we set up a View-based
Application that displays accelerometer data in three labels and
three progress bars.
The mainViewController.h file
@interface MainViewController : UIViewController <UIAccelerometerDelegate> {
IBOutlet UILabel *labelX;
IBOutlet UILabel *labelY;
IBOutlet UILabel *labelZ;
IBOutlet UIProgressView *progressX;
IBOutlet UIProgressView *progressY;
IBOutlet UIProgressView *progressZ;
UIAccelerometer *accelerometer;
}
@property (nonatomic, retain) IBOutlet UILabel *labelX;
@property (nonatomic, retain) IBOutlet UILabel *labelY;
@property (nonatomic, retain) IBOutlet UILabel *labelZ;
@property (nonatomic, retain) IBOutlet UIProgressView *progressX;
@property (nonatomic, retain) IBOutlet UIProgressView *progressY;
@property (nonatomic, retain) IBOutlet UIProgressView *progressZ;
@property (nonatomic, retain) UIAccelerometer *accelerometer;
The mainViewController.m file (1)
@synthesize labelX;
@synthesize labelY;
@synthesize labelZ;
@synthesize progressX;
@synthesize progressY;
@synthesize progressZ;
@synthesize accelerometer;
The mainViewController.m file (2)
- (void)viewDidLoad {
[super viewDidLoad];
self.accelerometer = [UIAccelerometer sharedAccelerometer];
self.accelerometer.updateInterval = .1;
self.accelerometer.delegate = self;
}
-
(void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration
*)acceleration {
labelX.text = [NSString stringWithFormat:@"%@%f", @"X: ", acceleration.x];
labelY.text = [NSString stringWithFormat:@"%@%f", @"Y: ", acceleration.y];
labelZ.text = [NSString stringWithFormat:@"%@%f", @"Z: ", acceleration.z];
self.progressX.progress = ABS(acceleration.x);
self.progressY.progress = ABS(acceleration.y);
self.progressZ.progress = ABS(acceleration.z);
}
Testing the accelerometer app
• The iPhone simulator does not natively support data from the
accelerometer, but there are a couple of plug-ins for Xcode that allow your
device to send that information to the simulator wirelessly.
• The free app, AccSim, is available on the App Store. The files it depends
upon (which have to be added to your Xcode project) are available at:
http://www.brianhpratt.net/cms/index.php?page=accsim
• A more robust app that also shares location and touch event data with the
simluator is iSimulate. It’s available on the App Store for $15.99. It has a
library which has to be embedded in your Xcode project that is available
here: http://www.vimov.com/isimulate/sdk/
• The advantage of both of these apps is that you don’t have to install your
project on your device to be able to test your code. They also provide a
convenient way to make video trailers of your apps that use accelerometer
input, like games.
Download