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

* Include iOS 16 Support
* Fix the unlock/lock issue by always calling setSupportedOrientations but only call setNeedsUpdateOfSupportedInterfaceOrientations at the end to avoid refreshing orientation twice
This commit is contained in:
oofaish 2022-12-12 00:55:43 +00:00 committed by GitHub
parent 98ec1cff7d
commit b444df630b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -28,6 +28,97 @@
@implementation 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 -(void)screenOrientation:(CDVInvokedUrlCommand *)command
{ {
CDVPluginResult* pluginResult; CDVPluginResult* pluginResult;
@ -47,43 +138,15 @@
if(orientationMask & 8) { if(orientationMask & 8) {
[result addObject:[NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft]]; [result addObject:[NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft]];
} }
SEL selector = NSSelectorFromString(@"setSupportedOrientations:"); SEL selector = NSSelectorFromString(@"setSupportedOrientations:");
if([vc respondsToSelector:selector]) { if([vc respondsToSelector:selector]) {
if (orientationMask != 15 || [UIDevice currentDevice] == nil) { if (orientationMask != 15 || [UIDevice currentDevice] == nil) {
((void (*)(CDVViewController*, SEL, NSMutableArray*))objc_msgSend)(vc,selector,result); ((void (*)(CDVViewController*, SEL, NSMutableArray*))objc_msgSend)(vc,selector,result);
} }
if ([UIDevice currentDevice] != nil){ if ([UIDevice currentDevice] != nil){
NSNumber *value = nil; [self handleWithOrientationMask:orientationMask viewController:vc result:result selector:selector];
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;
}
} }
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK]; pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];