Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save jzxchiang1/bd7e906038eb9a2c57857b5f1a0d6a3f to your computer and use it in GitHub Desktop.
Save jzxchiang1/bd7e906038eb9a2c57857b5f1a0d6a3f to your computer and use it in GitHub Desktop.
How to get accurate device orientation on iOS even with rotate lock turned on
diff --git a/node_modules/react-native-orientation-locker/iOS/RCTOrientation/Orientation.m b/node_modules/react-native-orientation-locker/iOS/RCTOrientation/Orientation.m
index 6117764..de9eaec 100644
--- a/node_modules/react-native-orientation-locker/iOS/RCTOrientation/Orientation.m
+++ b/node_modules/react-native-orientation-locker/iOS/RCTOrientation/Orientation.m
@@ -8,6 +8,7 @@
#import "Orientation.h"
+#import "RCTSensorOrientationChecker.h"
@implementation Orientation
@@ -15,6 +16,7 @@ @implementation Orientation
#if (!TARGET_OS_TV)
UIInterfaceOrientation _lastOrientation;
UIInterfaceOrientation _lastDeviceOrientation;
+ RCTSensorOrientationChecker * _sensorOrientationChecker;
#endif
BOOL _isLocking;
}
@@ -41,6 +43,7 @@ - (instancetype)init
_lastOrientation = [UIApplication sharedApplication].statusBarOrientation;;
_lastDeviceOrientation = (UIInterfaceOrientation) [UIDevice currentDevice].orientation;
_isLocking = NO;
+ _sensorOrientationChecker = [RCTSensorOrientationChecker new];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange:) name:UIDeviceOrientationDidChangeNotification object:nil];
[self addListener:@"orientationDidChange"];
@@ -166,9 +169,10 @@ - (void)lockToOrientation:(UIInterfaceOrientation) newOrientation usingMask:(UII
{
#if (!TARGET_OS_TV)
[[NSOperationQueue mainQueue] addOperationWithBlock:^ {
- UIInterfaceOrientation deviceOrientation = (UIInterfaceOrientation) [UIDevice currentDevice].orientation;
- NSString *orientationStr = [self getOrientationStr:deviceOrientation];
- callback(@[orientationStr]);
+ [_sensorOrientationChecker getDeviceOrientationWithBlock:^(UIInterfaceOrientation deviceOrientation) {
+ NSString *orientationStr = [self getOrientationStr:deviceOrientation];
+ callback(@[orientationStr]);
+ }];
}];
#endif
}
diff --git a/node_modules/react-native-orientation-locker/iOS/RCTOrientation/RCTSensorOrientationChecker.h b/node_modules/react-native-orientation-locker/iOS/RCTOrientation/RCTSensorOrientationChecker.h
new file mode 100644
index 0000000..15dc9e4
--- /dev/null
+++ b/node_modules/react-native-orientation-locker/iOS/RCTOrientation/RCTSensorOrientationChecker.h
@@ -0,0 +1,21 @@
+//
+// RCTSensorOrientationChecker.h
+// RCTCamera
+//
+// Created by Radu Popovici on 24/03/16.
+//
+//
+
+#import <UIKit/UIKit.h>
+#import <AVFoundation/AVFoundation.h>
+
+typedef void (^RCTSensorCallback) (UIInterfaceOrientation orientation);
+
+@interface RCTSensorOrientationChecker : NSObject
+
+@property (assign, nonatomic) UIInterfaceOrientation orientation;
+
+- (void)getDeviceOrientationWithBlock:(RCTSensorCallback)callback;
+- (AVCaptureVideoOrientation)convertToAVCaptureVideoOrientation:(UIInterfaceOrientation)orientation;
+
+@end
diff --git a/node_modules/react-native-orientation-locker/iOS/RCTOrientation/RCTSensorOrientationChecker.m b/node_modules/react-native-orientation-locker/iOS/RCTOrientation/RCTSensorOrientationChecker.m
new file mode 100644
index 0000000..fc0e457
--- /dev/null
+++ b/node_modules/react-native-orientation-locker/iOS/RCTOrientation/RCTSensorOrientationChecker.m
@@ -0,0 +1,105 @@
+//
+// RCTSensorOrientationChecker.m
+// RCTCamera
+//
+// Created by Radu Popovici on 24/03/16.
+//
+//
+
+#import "RCTSensorOrientationChecker.h"
+#import <CoreMotion/CoreMotion.h>
+
+
+@interface RCTSensorOrientationChecker ()
+
+@property (strong, nonatomic) CMMotionManager * motionManager;
+@property (strong, nonatomic) RCTSensorCallback orientationCallback;
+
+@end
+
+@implementation RCTSensorOrientationChecker
+
+- (instancetype)init
+{
+ self = [super init];
+ if (self) {
+ // Initialization code
+ self.motionManager = [[CMMotionManager alloc] init];
+ self.motionManager.accelerometerUpdateInterval = 0.2;
+ self.motionManager.gyroUpdateInterval = 0.2;
+ self.orientationCallback = nil;
+ }
+ return self;
+}
+
+- (void)dealloc
+{
+ [self pause];
+}
+
+- (void)resume
+{
+ __weak __typeof(self) weakSelf = self;
+ [self.motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue new]
+ withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) {
+ if (!error) {
+ self.orientation = [weakSelf getOrientationBy:accelerometerData.acceleration];
+ }
+ if (self.orientationCallback) {
+ self.orientationCallback(self.orientation);
+ }
+ }];
+}
+
+- (void)pause
+{
+ [self.motionManager stopAccelerometerUpdates];
+}
+
+- (void)getDeviceOrientationWithBlock:(RCTSensorCallback)callback
+{
+ __weak __typeof(self) weakSelf = self;
+ self.orientationCallback = ^(UIInterfaceOrientation orientation) {
+ if (callback) {
+ callback(orientation);
+ }
+ weakSelf.orientationCallback = nil;
+ [weakSelf pause];
+ };
+ [self resume];
+}
+
+- (UIInterfaceOrientation)getOrientationBy:(CMAcceleration)acceleration
+{
+ if(acceleration.x >= 0.75) {
+ return UIInterfaceOrientationLandscapeLeft;
+ }
+ if(acceleration.x <= -0.75) {
+ return UIInterfaceOrientationLandscapeRight;
+ }
+ if(acceleration.y <= -0.75) {
+ return UIInterfaceOrientationPortrait;
+ }
+ if(acceleration.y >= 0.75) {
+ return UIInterfaceOrientationPortraitUpsideDown;
+ }
+ return [[UIApplication sharedApplication] statusBarOrientation];
+}
+
+- (AVCaptureVideoOrientation)convertToAVCaptureVideoOrientation:(UIInterfaceOrientation)orientation
+{
+ switch (orientation) {
+ case UIInterfaceOrientationPortrait:
+ return AVCaptureVideoOrientationPortrait;
+ case UIInterfaceOrientationPortraitUpsideDown:
+ return AVCaptureVideoOrientationPortraitUpsideDown;
+ case UIInterfaceOrientationLandscapeLeft:
+ return AVCaptureVideoOrientationLandscapeLeft;
+ case UIInterfaceOrientationLandscapeRight:
+ return AVCaptureVideoOrientationLandscapeRight;
+ default:
+ return 0; // unknown
+ }
+}
+
+@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment