forked from tastyone/MotionOrientation
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
240 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// | ||
// MotionOrientation.h | ||
// | ||
// Created by Sangwon Park on 5/3/12. | ||
// Copyright (c) 2012 [email protected]. All rights reserved. | ||
// | ||
|
||
#import <CoreMotion/CoreMotion.h> | ||
#import <CoreGraphics/CoreGraphics.h> | ||
|
||
extern NSString* const MotionOrientationChangedNotification; | ||
extern NSString* const MotionOrientationInterfaceOrientationChangedNotification; | ||
|
||
extern NSString* const kMotionOrientationKey; | ||
|
||
@interface MotionOrientation : NSObject | ||
|
||
@property (readonly) UIInterfaceOrientation interfaceOrientation; | ||
@property (readonly) UIDeviceOrientation deviceOrientation; | ||
@property (readonly) CGAffineTransform affineTransform; | ||
|
||
+ (void)initialize; | ||
+ (MotionOrientation *)sharedInstance; | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,215 @@ | ||
// | ||
// MotionOrientation.m | ||
// | ||
// Created by Sangwon Park on 5/3/12. | ||
// Copyright (c) 2012 [email protected]. All rights reserved. | ||
// | ||
|
||
#import "MotionOrientation.h" | ||
|
||
#define MO_degreesToRadian(x) (M_PI * (x) / 180.0) | ||
|
||
NSString* const MotionOrientationChangedNotification = @"MotionOrientationChangedNotification"; | ||
NSString* const MotionOrientationInterfaceOrientationChangedNotification = @"MotionOrientationInterfaceOrientationChangedNotification"; | ||
|
||
NSString* const kMotionOrientationKey = @"kMotionOrientationKey"; | ||
|
||
@interface MotionOrientation () | ||
@property (strong) CMMotionManager* motionManager; | ||
@property (strong) NSOperationQueue* operationQueue; | ||
@end | ||
|
||
|
||
@implementation MotionOrientation | ||
|
||
@synthesize interfaceOrientation = _interfaceOrientation; | ||
@synthesize deviceOrientation = _deviceOrientation; | ||
|
||
@synthesize motionManager = _motionManager; | ||
@synthesize operationQueue = _operationQueue; | ||
|
||
+ (void)initialize | ||
{ | ||
[MotionOrientation sharedInstance]; | ||
} | ||
|
||
+ (MotionOrientation *)sharedInstance | ||
{ | ||
static MotionOrientation *sharedInstance = nil; | ||
static dispatch_once_t onceToken; | ||
dispatch_once(&onceToken, ^{ | ||
sharedInstance = [[MotionOrientation alloc] init]; | ||
// Do any other initialisation stuff here | ||
}); | ||
return sharedInstance; | ||
} | ||
|
||
- (void)_initialize | ||
{ | ||
self.operationQueue = [[NSOperationQueue alloc] init]; | ||
|
||
self.motionManager = [[CMMotionManager alloc] init]; | ||
self.motionManager.accelerometerUpdateInterval = 0.1; | ||
if ( ![self.motionManager isAccelerometerAvailable] ) { | ||
NSLog(@"MotionOrientation - Accelerometer is NOT available"); | ||
return; | ||
} | ||
if ( ![self.motionManager isAccelerometerActive] ) { | ||
NSLog(@"MotionOrientation - Accelerometer is NOT active"); | ||
return; | ||
} | ||
[self.motionManager startAccelerometerUpdatesToQueue:self.operationQueue withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) { | ||
[self accelerometerUpdateWithData:accelerometerData error:error]; | ||
}]; | ||
} | ||
|
||
- (id)init | ||
{ | ||
self = [super init]; | ||
if ( self ) { | ||
[self _initialize]; | ||
} | ||
return self; | ||
} | ||
|
||
- (CGAffineTransform)affineTransform | ||
{ | ||
int rotationDegree = 0; | ||
|
||
switch (self.interfaceOrientation) { | ||
case UIInterfaceOrientationPortrait: | ||
rotationDegree = 0; | ||
break; | ||
|
||
case UIInterfaceOrientationLandscapeLeft: | ||
rotationDegree = 90; | ||
break; | ||
|
||
case UIInterfaceOrientationPortraitUpsideDown: | ||
rotationDegree = 180; | ||
break; | ||
|
||
case UIInterfaceOrientationLandscapeRight: | ||
rotationDegree = 270; | ||
break; | ||
|
||
default: | ||
break; | ||
} | ||
NSLog(@"affineTransform degree: %d", rotationDegree); | ||
return CGAffineTransformMakeRotation(MO_degreesToRadian(rotationDegree)); | ||
} | ||
|
||
- (void)accelerometerUpdateWithData:(CMAccelerometerData *)accelerometerData error:(NSError *)error | ||
{ | ||
if ( error ) { | ||
NSLog(@"accelerometerUpdateERROR: %@", error); | ||
return; | ||
} | ||
|
||
CMAcceleration acceleration = accelerometerData.acceleration; | ||
|
||
// Get the current device angle | ||
float xx = -acceleration.x; | ||
float yy = acceleration.y; | ||
float z = acceleration.z; | ||
float angle = atan2(yy, xx); | ||
float absoluteZ = (float)fabs(acceleration.z); | ||
|
||
// Add 1.5 to the angle to keep the label constantly horizontal to the viewer. | ||
// [interfaceOrientationLabel setTransform:CGAffineTransformMakeRotation(angle+1.5)]; | ||
|
||
// Read my blog for more details on the angles. It should be obvious that you | ||
// could fire a custom shouldAutorotateToInterfaceOrientation-event here. | ||
UIInterfaceOrientation newInterfaceOrientation = self.interfaceOrientation; | ||
UIInterfaceOrientation newDeviceOrientation = self.deviceOrientation; | ||
|
||
#ifdef DEBUG | ||
NSString* orientationString = nil; | ||
#endif | ||
if(absoluteZ > 0.8f) | ||
{ | ||
if ( z > 0.0f ) { | ||
newDeviceOrientation = UIDeviceOrientationFaceDown; | ||
#ifdef DEBUG | ||
orientationString = @"MotionOrientation - FaceDown"; | ||
#endif | ||
} else { | ||
newDeviceOrientation = UIDeviceOrientationFaceUp; | ||
#ifdef DEBUG | ||
orientationString = @"MotionOrientation - FaceUp"; | ||
#endif | ||
} | ||
} | ||
else if(angle >= -2.0 && angle <= -1.0) // (angle >= -2.25 && angle <= -0.75) | ||
{ | ||
newInterfaceOrientation = UIInterfaceOrientationPortrait; | ||
newDeviceOrientation = UIDeviceOrientationPortrait; | ||
//self.captureVideoOrientation = AVCaptureVideoOrientationPortrait; | ||
#ifdef DEBUG | ||
orientationString = @"MotionOrientation - Portrait"; | ||
#endif | ||
} | ||
else if(angle >= -0.5 && angle <= 0.5) // (angle >= -0.75 && angle <= 0.75) | ||
{ | ||
newInterfaceOrientation = UIInterfaceOrientationLandscapeLeft; | ||
newDeviceOrientation = UIDeviceOrientationLandscapeLeft; | ||
//self.captureVideoOrientation = AVCaptureVideoOrientationLandscapeRight; | ||
#ifdef DEBUG | ||
orientationString = @"MotionOrientation - Left"; | ||
#endif | ||
} | ||
else if(angle >= 1.0 && angle <= 2.0) // (angle >= 0.75 && angle <= 2.25) | ||
{ | ||
newInterfaceOrientation = UIInterfaceOrientationPortraitUpsideDown; | ||
newDeviceOrientation = UIDeviceOrientationPortraitUpsideDown; | ||
//self.captureVideoOrientation = AVCaptureVideoOrientationPortraitUpsideDown; | ||
#ifdef DEBUG | ||
orientationString = @"MotionOrientation - UpsideDown"; | ||
#endif | ||
} | ||
else if(angle <= -2.5 || angle >= 2.5) // (angle <= -2.25 || angle >= 2.25) | ||
{ | ||
newInterfaceOrientation = UIInterfaceOrientationLandscapeRight; | ||
newDeviceOrientation = UIDeviceOrientationLandscapeRight; | ||
//self.captureVideoOrientation = AVCaptureVideoOrientationLandscapeLeft; | ||
#ifdef DEBUG | ||
orientationString = @"MotionOrientation - Right"; | ||
#endif | ||
} else { | ||
|
||
} | ||
|
||
BOOL deviceOrientationChanged = NO; | ||
BOOL interfaceOrientationChanged = NO; | ||
|
||
if ( newDeviceOrientation != self.deviceOrientation ) { | ||
deviceOrientationChanged = YES; | ||
_deviceOrientation = newDeviceOrientation; | ||
} | ||
|
||
if ( newInterfaceOrientation != self.interfaceOrientation ) { | ||
interfaceOrientationChanged = YES; | ||
_interfaceOrientation = newInterfaceOrientation; | ||
} | ||
|
||
// post notifications | ||
if ( deviceOrientationChanged ) { | ||
[[NSNotificationCenter defaultCenter] postNotificationName:MotionOrientationChangedNotification | ||
object:nil | ||
userInfo:[NSDictionary dictionaryWithObjectsAndKeys:self, kMotionOrientationKey, nil]]; | ||
#ifdef DEBUG | ||
NSLog(@"didAccelerate: absoluteZ: %f angle: %f (x: %f, y: %f, z: %f), orientationString: %@", | ||
absoluteZ, angle, | ||
acceleration.x, acceleration.y, acceleration.z, | ||
orientationString); | ||
#endif | ||
} | ||
if ( interfaceOrientationChanged ) { | ||
[[NSNotificationCenter defaultCenter] postNotificationName:MotionOrientationInterfaceOrientationChangedNotification | ||
object:nil | ||
userInfo:[NSDictionary dictionaryWithObjectsAndKeys:self, kMotionOrientationKey, nil]]; | ||
} | ||
} | ||
|
||
@end |