Closed Itrainlcincom closed 1 year ago
i am also facing same issue but for me its also not working in ios 15.6.1
my specs are
"react-native-orientation": "^3.1.3", "react": "17.0.1", "react-native": "0.64.1",
and in app deleagte
already imported orientation.h file in app delegate and method
(UIInterfaceOrientationMask)application:(UIApplication )application supportedInterfaceOrientationsForWindow:(UIWindow )window { return [Orientation getOrientation]; }
let me know if i am doing anything wrong and can you confirm in real device which have lower version then 16 its working or not
Hi. After update iOS 16.1.1 -> Orientation.addOrientationListener(_orientationDidChange) does not call _orientationDidChange
I have investigated in IOS, [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange:) name:@"UIDeviceOrientationDidChangeNotification" object:nil]; } does not call deviceOrientationDidChange method.
How to fix this bug? Please help me.
On iOS 15.6.1
- Call lockToLandscape(RCT_EXPORT_METHOD(lockToLandscape)) -> deviceOrientationDidChange method is called.
On iOS 16.1.1
- Call lockToLandscape(RCT_EXPORT_METHOD(lockToLandscape)) -> deviceOrientationDidChange method is not called.
@Itrainlcincom can you please confirm that its working fine in lower version device like ios 14 or 15 with xcode 13.1
Hello. It is working fine in lower version, it is only error with 16.
This is code of me, it is working fine on all versions.
(void)lockToOrientation:(UIInterfaceOrientation) newOrientation usingMask:(UIInterfaceOrientationMask) mask { // set a flag so that no deviceOrientationDidChange events are sent to JS _isLocking = YES; NSString* orientation = @"orientation";
UIInterfaceOrientation deviceOrientation = _lastDeviceOrientation;
[Orientation setOrientation:mask];
if (@available(iOS 16.0, )) { NSArray array = [[[UIApplication sharedApplication] connectedScenes] allObjects]; UIWindowScene scene = (UIWindowScene )array[0]; UIWindowSceneGeometryPreferencesIOS geometryPreferences = [[UIWindowSceneGeometryPreferencesIOS alloc] initWithInterfaceOrientations:mask]; [scene requestGeometryUpdateWithPreferences:geometryPreferences errorHandler:^(NSError _Nonnull error) { }]; } else { // UIDevice* currentDevice = [UIDevice currentDevice]; // [currentDevice setValue:@(UIInterfaceOrientationUnknown) forKey:orientation]; // [currentDevice setValue:@(newOrientation) forKey:orientation];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; [[UIDevice currentDevice] setValue:@(newOrientation) forKey:@"orientation"]; }
[UIViewController attemptRotationToDeviceOrientation];
[self sendEventWithName:@"lockDidChange" body:@{orientation: [self getOrientationStr:newOrientation]}];
_isLocking = NO; }
@Itrainlcincom can you please share your complete file because its still not working for me on lower versions
@Itrainlcincom this is my complete code and its working in ios 16 but not in lower versions
// // Orientation.m //
@implementation Orientation @synthesize bridge = _bridge;
static UIInterfaceOrientationMask _orientation = UIInterfaceOrientationMaskAllButUpsideDown;
(void)setOrientation: (UIInterfaceOrientationMask)orientation { _orientation = orientation; }
(UIInterfaceOrientationMask)getOrientation { return _orientation; }
(instancetype)init { if ((self = [super init])) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange:) name:@"UIDeviceOrientationDidChangeNotification" object:nil]; } return self;
}
(void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; }
(BOOL)requiresMainQueueSetup { return YES; }
(void)dispatchOrientationChangeEvent:(UIDeviceOrientation)orientation { [self.bridge.eventDispatcher sendDeviceEventWithName:@"specificOrientationDidChange" body:@{@"specificOrientation": [self getSpecificOrientationStr:orientation]}];
[self.bridge.eventDispatcher sendDeviceEventWithName:@"orientationDidChange" body:@{@"orientation": [self getOrientationStr:orientation]}]; }
(void)lockToOrientationWithMask:(UIInterfaceOrientationMask)maskOrientation interfaceOrientation:(UIInterfaceOrientation)interfaceOrientation deviceOrientation:(UIDeviceOrientation)deviceOrientation { if (@available(iOS 16, *)) {
dispatch_sync(dispatch_get_main_queue(), ^{
NSArray *array = [[[UIApplication sharedApplication] connectedScenes] allObjects];
UIWindowScene *scene = (UIWindowScene *)array[0];
[UIViewController attemptRotationToDeviceOrientation];
UIWindowSceneGeometryPreferencesIOS *geometryPreferences = [[UIWindowSceneGeometryPreferencesIOS alloc] initWithInterfaceOrientations:maskOrientation];
[scene requestGeometryUpdateWithPreferences:geometryPreferences errorHandler:^(NSError * _Nonnull error) {
NSLog(@"Error-->%@",[error localizedDescription]);
}];
});
[self dispatchOrientationChangeEvent:deviceOrientation];
} else { [[NSOperationQueue mainQueue] addOperationWithBlock:^ { [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:interfaceOrientation] forKey:@"orientation"]; [UIViewController attemptRotationToDeviceOrientation]; }]; } }
(void)deviceOrientationDidChange:(NSNotification *)notification { UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; [self dispatchOrientationChangeEvent:orientation]; }
(NSString )getOrientationStr: (UIDeviceOrientation)orientation { NSString orientationStr; switch (orientation) { case UIDeviceOrientationPortrait: orientationStr = @"PORTRAIT"; break; case UIDeviceOrientationLandscapeLeft: case UIDeviceOrientationLandscapeRight:
orientationStr = @"LANDSCAPE"; break;
case UIDeviceOrientationPortraitUpsideDown: orientationStr = @"PORTRAITUPSIDEDOWN"; break;
default: // orientation is unknown, we try to get the status bar orientation switch ([[UIApplication sharedApplication] statusBarOrientation]) { case UIInterfaceOrientationPortrait: orientationStr = @"PORTRAIT"; break; case UIInterfaceOrientationLandscapeLeft: case UIInterfaceOrientationLandscapeRight:
orientationStr = @"LANDSCAPE";
break;
case UIInterfaceOrientationPortraitUpsideDown:
orientationStr = @"PORTRAITUPSIDEDOWN";
break;
default:
orientationStr = @"UNKNOWN";
break;
} break; } return orientationStr; }
(NSString )getSpecificOrientationStr: (UIDeviceOrientation)orientation { NSString orientationStr; switch (orientation) { case UIDeviceOrientationPortrait: orientationStr = @"PORTRAIT"; break;
case UIDeviceOrientationLandscapeLeft: orientationStr = @"LANDSCAPE-LEFT"; break;
case UIDeviceOrientationLandscapeRight: orientationStr = @"LANDSCAPE-RIGHT"; break;
case UIDeviceOrientationPortraitUpsideDown: orientationStr = @"PORTRAITUPSIDEDOWN"; break;
default: // orientation is unknown, we try to get the status bar orientation switch ([[UIApplication sharedApplication] statusBarOrientation]) { case UIInterfaceOrientationPortrait: orientationStr = @"PORTRAIT"; break; case UIInterfaceOrientationLandscapeLeft: case UIInterfaceOrientationLandscapeRight:
orientationStr = @"LANDSCAPE";
break;
case UIInterfaceOrientationPortraitUpsideDown:
orientationStr = @"PORTRAITUPSIDEDOWN";
break;
default:
orientationStr = @"UNKNOWN";
break;
} break; } return orientationStr; }
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(getOrientation:(RCTResponseSenderBlock)callback) { UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; NSString *orientationStr = [self getOrientationStr:orientation]; callback(@[[NSNull null], orientationStr]); }
RCT_EXPORT_METHOD(getSpecificOrientation:(RCTResponseSenderBlock)callback) { UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; NSString *orientationStr = [self getSpecificOrientationStr:orientation]; callback(@[[NSNull null], orientationStr]); }
RCT_EXPORT_METHOD(lockToPortrait) {
NSLog(@"Locked to Portrait");
[Orientation setOrientation:UIInterfaceOrientationMaskPortrait];
[self lockToOrientationWithMask:UIInterfaceOrientationMaskPortrait interfaceOrientation:UIInterfaceOrientationPortrait deviceOrientation:UIDeviceOrientationPortrait];
}
RCT_EXPORT_METHOD(lockToLandscape) {
NSLog(@"Locked to Landscape");
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; NSString *orientationStr = [self getSpecificOrientationStr:orientation]; if ([orientationStr isEqualToString:@"LANDSCAPE-LEFT"]) { [Orientation setOrientation:UIInterfaceOrientationMaskLandscapeRight]; [self lockToOrientationWithMask:UIInterfaceOrientationMaskLandscapeRight interfaceOrientation:UIInterfaceOrientationLandscapeRight deviceOrientation:UIDeviceOrientationLandscapeRight]; } else { [Orientation setOrientation:UIInterfaceOrientationMaskLandscapeLeft]; [self lockToOrientationWithMask:UIInterfaceOrientationMaskLandscapeLeft interfaceOrientation:UIInterfaceOrientationLandscapeLeft deviceOrientation:UIDeviceOrientationLandscapeLeft]; } }
RCT_EXPORT_METHOD(lockToLandscapeLeft) {
NSLog(@"Locked to Landscape Left");
[Orientation setOrientation:UIInterfaceOrientationMaskLandscapeLeft];
[self lockToOrientationWithMask:UIInterfaceOrientationMaskLandscapeLeft interfaceOrientation:UIInterfaceOrientationLandscapeLeft deviceOrientation:UIDeviceOrientationLandscapeLeft];
}
RCT_EXPORT_METHOD(lockToLandscapeRight) {
NSLog(@"Locked to Landscape Right");
[Orientation setOrientation:UIInterfaceOrientationMaskLandscapeRight];
[self lockToOrientationWithMask:UIInterfaceOrientationMaskLandscapeRight interfaceOrientation:UIInterfaceOrientationLandscapeRight deviceOrientation:UIDeviceOrientationLandscapeRight];
}
RCT_EXPORT_METHOD(unlockAllOrientations) {
NSLog(@"Unlock All Orientations");
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; [Orientation setOrientation:UIInterfaceOrientationMaskAllButUpsideDown]; [self lockToOrientationWithMask:UIInterfaceOrientationMaskAllButUpsideDown interfaceOrientation:UIInterfaceOrientationMaskAllButUpsideDown deviceOrientation:orientation]; }
(NSDictionary *)constantsToExport {
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; NSString *orientationStr = [self getOrientationStr:orientation];
return @{ @"initialOrientation": orientationStr }; }
@end
@Itrainlcincom and in app delegate i have this
Hi. You should use code from this library. https://www.npmjs.com/package/react-native-orientation-locker And custom Orientation.m // // react-native-orientation-locker // Orientation.m // // Created by Wonday on 17/5/12. // Copyright (c) wonday.org All rights reserved. //
@implementation Orientation {
UIInterfaceOrientation _lastOrientation;
UIInterfaceOrientation _lastDeviceOrientation;
BOOL _disableFaceUpDown;
BOOL _isLocking;
}
static UIInterfaceOrientationMask _orientationMask = UIInterfaceOrientationMaskAll;
(void)setOrientation: (UIInterfaceOrientationMask)orientationMask { _orientationMask = orientationMask; }
(UIInterfaceOrientationMask)getOrientation { return _orientationMask; }
(NSArray<NSString > )supportedEvents { return @[@"orientationDidChange",@"deviceOrientationDidChange",@"lockDidChange"]; }
(instancetype)init { if ((self = [super init])) { _lastOrientation = [UIApplication sharedApplication].statusBarOrientation;; _lastDeviceOrientation = [self getDeviceOrientation]; _isLocking = NO; _disableFaceUpDown = NO;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange:) name:UIDeviceOrientationDidChangeNotification object:nil];
[self addListener:@"orientationDidChange"];
} return self; }
(void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; [self removeListeners:1]; }
(UIInterfaceOrientation)getDeviceOrientation { UIInterfaceOrientation deviceOrientation = (UIInterfaceOrientation) [UIDevice currentDevice].orientation;
BOOL isFaceUpDown = deviceOrientation == UIDeviceOrientationFaceUp || deviceOrientation == UIDeviceOrientationFaceDown; if (_disableFaceUpDown && isFaceUpDown) { return [UIApplication sharedApplication].statusBarOrientation; }
return deviceOrientation; }
(void)deviceOrientationDidChange:(NSNotification *)notification { UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; UIInterfaceOrientation deviceOrientation = [self getDeviceOrientation];
// do not send Unknown Orientation if (deviceOrientation==UIInterfaceOrientationUnknown) { return; }
if (orientation!=UIInterfaceOrientationUnknown && orientation!=_lastOrientation) { [self sendEventWithName:@"orientationDidChange" body:@{@"orientation": [self getOrientationStr:orientation]}]; _lastOrientation = orientation; }
// when call lockToXXX, not sent deviceOrientationDidChange if (!_isLocking && deviceOrientation!=_lastDeviceOrientation) { [self sendEventWithName:@"deviceOrientationDidChange" body:@{@"deviceOrientation":[self getOrientationStr:deviceOrientation]}]; _lastDeviceOrientation = deviceOrientation; } }
(NSString *)getOrientationStr: (UIInterfaceOrientation)orientation {
NSString *orientationStr; switch (orientation) { case UIInterfaceOrientationPortrait:
orientationStr = @"PORTRAIT";
break;
case UIInterfaceOrientationLandscapeLeft:
orientationStr = @"LANDSCAPE-RIGHT";
break;
case UIInterfaceOrientationLandscapeRight:
orientationStr = @"LANDSCAPE-LEFT";
break;
case UIInterfaceOrientationPortraitUpsideDown:
orientationStr = @"PORTRAIT-UPSIDEDOWN";
break;
case UIDeviceOrientationFaceUp:
orientationStr = @"FACE-UP";
break;
case UIDeviceOrientationFaceDown:
orientationStr = @"FACE-DOWN";
break;
default:
orientationStr = @"UNKNOWN";
break;
} return orientationStr; }
(void)lockToOrientation:(UIInterfaceOrientation) newOrientation usingMask:(UIInterfaceOrientationMask) mask { // set a flag so that no deviceOrientationDidChange events are sent to JS _isLocking = YES; NSString* orientation = @"orientation";
UIInterfaceOrientation deviceOrientation = _lastDeviceOrientation;
[Orientation setOrientation:mask];
if (@available(iOS 16.0, )) { NSArray array = [[[UIApplication sharedApplication] connectedScenes] allObjects]; UIWindowScene scene = (UIWindowScene )array[0]; UIWindowSceneGeometryPreferencesIOS geometryPreferences = [[UIWindowSceneGeometryPreferencesIOS alloc] initWithInterfaceOrientations:mask]; [scene requestGeometryUpdateWithPreferences:geometryPreferences errorHandler:^(NSError _Nonnull error) { }]; } else { // UIDevice* currentDevice = [UIDevice currentDevice]; // [currentDevice setValue:@(UIInterfaceOrientationUnknown) forKey:orientation]; // [currentDevice setValue:@(newOrientation) forKey:orientation];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; [[UIDevice currentDevice] setValue:@(newOrientation) forKey:@"orientation"]; }
[UIViewController attemptRotationToDeviceOrientation];
[self sendEventWithName:@"lockDidChange" body:@{orientation: [self getOrientationStr:newOrientation]}];
_isLocking = NO; }
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(configure:(NSDictionary *)options) {
NSLog(@"Configure called with options: %@", options);
_disableFaceUpDown = [options objectForKey:@"disableFaceUpDown"] != nil;
}
RCT_EXPORT_METHOD(getOrientation:(RCTResponseSenderBlock)callback) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^ {
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
NSString *orientationStr = [self getOrientationStr:orientation];
callback(@[orientationStr]);
}];
}
RCT_EXPORT_METHOD(getDeviceOrientation:(RCTResponseSenderBlock)callback) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^ {
UIInterfaceOrientation deviceOrientation = [self getDeviceOrientation];
NSString *orientationStr = [self getOrientationStr:deviceOrientation];
callback(@[orientationStr]);
}];
}
RCT_EXPORT_METHOD(lockToPortrait) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^ {
[self lockToOrientation:UIInterfaceOrientationPortrait usingMask:UIInterfaceOrientationMaskPortrait];
}];
}
RCT_EXPORT_METHOD(lockToPortraitUpsideDown) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^ {
[self lockToOrientation:UIInterfaceOrientationPortraitUpsideDown usingMask:UIInterfaceOrientationMaskPortraitUpsideDown];
}];
}
RCT_EXPORT_METHOD(lockToLandscape)
{
NSLog(@"Locking to Landscape");
[[NSOperationQueue mainQueue] addOperationWithBlock:^ {
// set a flag so that no deviceOrientationDidChange events are sent to JS
// self->_isLocking = YES;
// UIInterfaceOrientation deviceOrientation = self->_lastDeviceOrientation;
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
NSString *orientationStr = [self getOrientationStr:orientation];
// when call lockXXX, make sure to sent orientationDidChange event to JS
// [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger: UIInterfaceOrientationUnknown] forKey:@"orientation"];
if ([orientationStr isEqualToString:@"LANDSCAPE-RIGHT"]) {
[self lockToOrientation:UIInterfaceOrientationLandscapeLeft usingMask:UIInterfaceOrientationMaskLandscapeLeft];
// [Orientation setOrientation:UIInterfaceOrientationMaskLandscape]; // [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger: UIInterfaceOrientationLandscapeLeft] forKey:@"orientation"]; } else { [self lockToOrientation:UIInterfaceOrientationLandscapeRight usingMask:UIInterfaceOrientationMaskLandscapeRight]; // [Orientation setOrientation:UIInterfaceOrientationMaskLandscape]; // [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger: UIInterfaceOrientationLandscapeRight] forKey:@"orientation"]; }
// restore device orientation
// [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger: deviceOrientation] forKey:@"orientation"];
// [UIViewController attemptRotationToDeviceOrientation];
// send a lock event
// [self sendEventWithName:@"lockDidChange" body:@{@"orientation":@"LANDSCAPE-LEFT"}];
// self->_isLocking = NO;
}];
// [[NSOperationQueue mainQueue] addOperationWithBlock:^ { // [self lockToOrientation:UIInterfaceOrientationLandscapeLeft usingMask:UIInterfaceOrientationMaskLandscapeLeft]; // }];
}
RCT_EXPORT_METHOD(lockToLandscapeRight) {
NSLog(@"Locking to Landscape Right");
[[NSOperationQueue mainQueue] addOperationWithBlock:^ {
[self lockToOrientation:UIInterfaceOrientationLandscapeLeft usingMask:UIInterfaceOrientationMaskLandscapeLeft];
}];
}
RCT_EXPORT_METHOD(lockToLandscapeLeft) {
NSLog(@"Locking to Landscape Left");
[[NSOperationQueue mainQueue] addOperationWithBlock:^ {
[self lockToOrientation:UIInterfaceOrientationLandscapeRight usingMask:UIInterfaceOrientationMaskLandscapeRight];
}];
}
RCT_EXPORT_METHOD(lockToAllOrientationsButUpsideDown) {
NSLog(@"Locking to all except upside down");
[[NSOperationQueue mainQueue] addOperationWithBlock:^ {
[self lockToOrientation:UIInterfaceOrientationPortrait usingMask:UIInterfaceOrientationMaskAllButUpsideDown];
}];
}
RCT_EXPORT_METHOD(unlockAllOrientations) {
NSLog(@"Unlocking All Orientations");
[[NSOperationQueue mainQueue] addOperationWithBlock:^ {
[self lockToOrientation:UIInterfaceOrientationUnknown usingMask:UIInterfaceOrientationMaskAll];
}];
}
(NSDictionary *)constantsToExport {
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; NSString *orientationStr = [self getOrientationStr:orientation];
return @{@"initialOrientation": orientationStr};
return nil; }
(BOOL)requiresMainQueueSetup { return YES; }
@end
In AppAppDelegate.m
In JS, you copy folder src from https://www.npmjs.com/package/react-native-orientation-locker (you download it) and paste to your project.
You use orientation in your code.
import Orientation, { useOrientationChange, useLockListener, useDeviceOrientationChange, } from "../../../src/hooks/index";
You read more document in https://www.npmjs.com/package/react-native-orientation-locker
This https://www.npmjs.com/package/react-native-orientation-locker is not working low version 16, I must be custom code in file orientation.m
Hi. This library is not working with iOS 16 This https://www.npmjs.com/package/react-native-orientation-locker is not working low version 16. So I must custom code.
Hi. After update iOS 16.1.1 -> Orientation.addOrientationListener(_orientationDidChange) does not call _orientationDidChange
I have investigated in IOS, [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange:) name:@"UIDeviceOrientationDidChangeNotification" object:nil]; } does not call deviceOrientationDidChange method.
How to fix this bug? Please help me.
On iOS 15.6.1
On iOS 16.1.1