Skip to content

feat(ios): add support for ios 16 #107

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Dec 12, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 93 additions & 30 deletions src/ios/CDVOrientation.m
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,97 @@ @interface CDVOrientation () {}

@implementation CDVOrientation


-(void)handleBelowEqualIos15WithOrientationMask:(NSInteger) orientationMask viewController: (CDVViewController*) vc result:(NSMutableArray*) result selector:(SEL) selector
{
NSValue *value;
if (orientationMask != 15) {
if (!_isLocked) {
_lastOrientation = [UIApplication sharedApplication].statusBarOrientation;
}
UIInterfaceOrientation deviceOrientation = [UIApplication sharedApplication].statusBarOrientation;
if(orientationMask == 8 || (orientationMask == 12 && !UIInterfaceOrientationIsLandscape(deviceOrientation))) {
value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
} else if (orientationMask == 4){
value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight];
} else if (orientationMask == 1 || (orientationMask == 3 && !UIInterfaceOrientationIsPortrait(deviceOrientation))) {
value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
} else if (orientationMask == 2) {
value = [NSNumber numberWithInt:UIInterfaceOrientationPortraitUpsideDown];
}
} else {
if (_lastOrientation != UIInterfaceOrientationUnknown) {
[[UIDevice currentDevice] setValue:[NSNumber numberWithInt:_lastOrientation] forKey:@"orientation"];
((void (*)(CDVViewController*, SEL, NSMutableArray*))objc_msgSend)(vc,selector,result);
[UINavigationController attemptRotationToDeviceOrientation];
}
}
if (value != nil) {
_isLocked = true;
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];
} else {
_isLocked = false;
}
}

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 160000
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunguarded-availability-new"
// this will stop it complaining about new iOS16 APIs being used.
-(void)handleAboveEqualIos16WithOrientationMask:(NSInteger) orientationMask viewController: (CDVViewController*) vc result:(NSMutableArray*) result selector:(SEL) selector
{
NSObject *value;
// oritentationMask 15 is "unlock" the orientation lock.
if (orientationMask != 15) {
if (!_isLocked) {
_lastOrientation = [UIApplication sharedApplication].statusBarOrientation;
}
UIInterfaceOrientation deviceOrientation = [UIApplication sharedApplication].statusBarOrientation;
if(orientationMask == 8 || (orientationMask == 12 && !UIInterfaceOrientationIsLandscape(deviceOrientation))) {
value = [[UIWindowSceneGeometryPreferencesIOS alloc] initWithInterfaceOrientations:UIInterfaceOrientationMaskLandscapeLeft];
} else if (orientationMask == 4){
value = [[UIWindowSceneGeometryPreferencesIOS alloc] initWithInterfaceOrientations:UIInterfaceOrientationMaskLandscapeRight];
} else if (orientationMask == 1 || (orientationMask == 3 && !UIInterfaceOrientationIsPortrait(deviceOrientation))) {
value = [[UIWindowSceneGeometryPreferencesIOS alloc] initWithInterfaceOrientations:UIInterfaceOrientationMaskPortrait];
} else if (orientationMask == 2) {
value = [[UIWindowSceneGeometryPreferencesIOS alloc] initWithInterfaceOrientations:UIInterfaceOrientationMaskPortraitUpsideDown];
}
} else {
((void (*)(CDVViewController*, SEL, NSMutableArray*))objc_msgSend)(vc,selector,result);
}
if (value != nil) {
_isLocked = true;
UIWindowScene *scene = (UIWindowScene*)[[UIApplication.sharedApplication connectedScenes] anyObject];
[scene requestGeometryUpdateWithPreferences:(UIWindowSceneGeometryPreferencesIOS*)value errorHandler:^(NSError * _Nonnull error) {
NSLog(@"Failed to change orientation %@ %@", error, [error userInfo]);
}];
} else {
_isLocked = false;
}
}
#pragma clang diagnostic pop

-(void)handleWithOrientationMask:(NSInteger) orientationMask viewController: (CDVViewController*) vc result:(NSMutableArray*) result selector:(SEL) selector
{
if (@available(iOS 16.0, *)) {
[self handleAboveEqualIos16WithOrientationMask:orientationMask viewController:vc result:result selector:selector];
// always double check the supported interfaces, so we update if needed
// but do it right at the end here to avoid the "double" rotation issue reported in
// https://github.com/apache/cordova-plugin-screen-orientation/pull/107
[self.viewController setNeedsUpdateOfSupportedInterfaceOrientations];
} else {
[self handleBelowEqualIos15WithOrientationMask:orientationMask viewController:vc result:result selector:selector];
}

}
#else
-(void)handleWithOrientationMask:(NSInteger) orientationMask viewController: (CDVViewController*) vc result:(NSMutableArray*) result selector:(SEL) selector
{
[self handleBelowEqualIos15WithOrientationMask:orientationMask viewController:vc result:result selector:selector];
}
#endif


-(void)screenOrientation:(CDVInvokedUrlCommand *)command
{
CDVPluginResult* pluginResult;
Expand All @@ -47,43 +138,15 @@ -(void)screenOrientation:(CDVInvokedUrlCommand *)command
if(orientationMask & 8) {
[result addObject:[NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft]];
}

SEL selector = NSSelectorFromString(@"setSupportedOrientations:");

if([vc respondsToSelector:selector]) {
if (orientationMask != 15 || [UIDevice currentDevice] == nil) {
((void (*)(CDVViewController*, SEL, NSMutableArray*))objc_msgSend)(vc,selector,result);
}

if ([UIDevice currentDevice] != nil){
NSNumber *value = nil;
if (orientationMask != 15) {
if (!_isLocked) {
_lastOrientation = [UIApplication sharedApplication].statusBarOrientation;
}
UIInterfaceOrientation deviceOrientation = [UIApplication sharedApplication].statusBarOrientation;
if(orientationMask == 8 || (orientationMask == 12 && !UIInterfaceOrientationIsLandscape(deviceOrientation))) {
value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
} else if (orientationMask == 4){
value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight];
} else if (orientationMask == 1 || (orientationMask == 3 && !UIInterfaceOrientationIsPortrait(deviceOrientation))) {
value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
} else if (orientationMask == 2) {
value = [NSNumber numberWithInt:UIInterfaceOrientationPortraitUpsideDown];
}
} else {
if (_lastOrientation != UIInterfaceOrientationUnknown) {
[[UIDevice currentDevice] setValue:[NSNumber numberWithInt:_lastOrientation] forKey:@"orientation"];
((void (*)(CDVViewController*, SEL, NSMutableArray*))objc_msgSend)(vc,selector,result);
[UINavigationController attemptRotationToDeviceOrientation];
}
}
if (value != nil) {
_isLocked = true;
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];
} else {
_isLocked = false;
}
[self handleWithOrientationMask:orientationMask viewController:vc result:result selector:selector];
}

pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
Expand Down