Skip to content

Commit 2d08636

Browse files
committed
break up ios16 into a seperate function + fix the unlock/lock issue by always calling setSupportedOrientations but only call setNeedsUpdateOfSupportedInterfaceOrientations at the end to avoid refreshing orientation twice
1 parent 98ec1cf commit 2d08636

File tree

1 file changed

+76
-28
lines changed

1 file changed

+76
-28
lines changed

src/ios/CDVOrientation.m

+76-28
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,74 @@ @interface CDVOrientation () {}
2828

2929
@implementation CDVOrientation
3030

31+
-(void)handleAboveEqualIos16WithOrientationMask:(NSInteger) orientationMask viewController: (CDVViewController*) vc result:(NSMutableArray*) result selector:(SEL) selector
32+
{
33+
if(@available(iOS 16.0, *)) {
34+
NSObject *value16;
35+
// oritentationMask 15 is "unlock" the orientation lock.
36+
if (orientationMask != 15) {
37+
if (!_isLocked) {
38+
_lastOrientation = [UIApplication sharedApplication].statusBarOrientation;
39+
}
40+
UIInterfaceOrientation deviceOrientation = [UIApplication sharedApplication].statusBarOrientation;
41+
if(orientationMask == 8 || (orientationMask == 12 && !UIInterfaceOrientationIsLandscape(deviceOrientation))) {
42+
value16 = [[UIWindowSceneGeometryPreferencesIOS alloc] initWithInterfaceOrientations:UIInterfaceOrientationMaskLandscapeLeft];
43+
} else if (orientationMask == 4){
44+
value16 = [[UIWindowSceneGeometryPreferencesIOS alloc] initWithInterfaceOrientations:UIInterfaceOrientationMaskLandscapeRight];
45+
} else if (orientationMask == 1 || (orientationMask == 3 && !UIInterfaceOrientationIsPortrait(deviceOrientation))) {
46+
value16 = [[UIWindowSceneGeometryPreferencesIOS alloc] initWithInterfaceOrientations:UIInterfaceOrientationMaskPortrait];
47+
} else if (orientationMask == 2) {
48+
value16 = [[UIWindowSceneGeometryPreferencesIOS alloc] initWithInterfaceOrientations:UIInterfaceOrientationMaskPortraitUpsideDown];
49+
}
50+
} else {
51+
((void (*)(CDVViewController*, SEL, NSMutableArray*))objc_msgSend)(vc,selector,result);
52+
}
53+
if (value16 != nil) {
54+
_isLocked = true;
55+
UIWindowScene *scene = (UIWindowScene*)[[UIApplication.sharedApplication connectedScenes] anyObject];
56+
[scene requestGeometryUpdateWithPreferences:(UIWindowSceneGeometryPreferencesIOS*)value16 errorHandler:^(NSError * _Nonnull error) {
57+
NSLog(@"Failed to change orientation %@ %@", error, [error userInfo]);
58+
}];
59+
} else {
60+
_isLocked = false;
61+
}
62+
}
63+
}
64+
65+
66+
-(void)handleBelowEqualIos15WithOrientationMask:(NSInteger) orientationMask viewController: (CDVViewController*) vc result:(NSMutableArray*) result selector:(SEL) selector
67+
{
68+
NSValue *value;
69+
if (orientationMask != 15) {
70+
if (!_isLocked) {
71+
_lastOrientation = [UIApplication sharedApplication].statusBarOrientation;
72+
}
73+
UIInterfaceOrientation deviceOrientation = [UIApplication sharedApplication].statusBarOrientation;
74+
if(orientationMask == 8 || (orientationMask == 12 && !UIInterfaceOrientationIsLandscape(deviceOrientation))) {
75+
value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
76+
} else if (orientationMask == 4){
77+
value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight];
78+
} else if (orientationMask == 1 || (orientationMask == 3 && !UIInterfaceOrientationIsPortrait(deviceOrientation))) {
79+
value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
80+
} else if (orientationMask == 2) {
81+
value = [NSNumber numberWithInt:UIInterfaceOrientationPortraitUpsideDown];
82+
}
83+
} else {
84+
if (_lastOrientation != UIInterfaceOrientationUnknown) {
85+
[[UIDevice currentDevice] setValue:[NSNumber numberWithInt:_lastOrientation] forKey:@"orientation"];
86+
((void (*)(CDVViewController*, SEL, NSMutableArray*))objc_msgSend)(vc,selector,result);
87+
[UINavigationController attemptRotationToDeviceOrientation];
88+
}
89+
}
90+
if (value != nil) {
91+
_isLocked = true;
92+
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];
93+
} else {
94+
_isLocked = false;
95+
}
96+
}
97+
98+
3199
-(void)screenOrientation:(CDVInvokedUrlCommand *)command
32100
{
33101
CDVPluginResult* pluginResult;
@@ -47,42 +115,22 @@ -(void)screenOrientation:(CDVInvokedUrlCommand *)command
47115
if(orientationMask & 8) {
48116
[result addObject:[NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft]];
49117
}
50-
51118
SEL selector = NSSelectorFromString(@"setSupportedOrientations:");
52119

53120
if([vc respondsToSelector:selector]) {
54121
if (orientationMask != 15 || [UIDevice currentDevice] == nil) {
55122
((void (*)(CDVViewController*, SEL, NSMutableArray*))objc_msgSend)(vc,selector,result);
56123
}
57-
124+
58125
if ([UIDevice currentDevice] != nil){
59-
NSNumber *value = nil;
60-
if (orientationMask != 15) {
61-
if (!_isLocked) {
62-
_lastOrientation = [UIApplication sharedApplication].statusBarOrientation;
63-
}
64-
UIInterfaceOrientation deviceOrientation = [UIApplication sharedApplication].statusBarOrientation;
65-
if(orientationMask == 8 || (orientationMask == 12 && !UIInterfaceOrientationIsLandscape(deviceOrientation))) {
66-
value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
67-
} else if (orientationMask == 4){
68-
value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight];
69-
} else if (orientationMask == 1 || (orientationMask == 3 && !UIInterfaceOrientationIsPortrait(deviceOrientation))) {
70-
value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
71-
} else if (orientationMask == 2) {
72-
value = [NSNumber numberWithInt:UIInterfaceOrientationPortraitUpsideDown];
73-
}
74-
} else {
75-
if (_lastOrientation != UIInterfaceOrientationUnknown) {
76-
[[UIDevice currentDevice] setValue:[NSNumber numberWithInt:_lastOrientation] forKey:@"orientation"];
77-
((void (*)(CDVViewController*, SEL, NSMutableArray*))objc_msgSend)(vc,selector,result);
78-
[UINavigationController attemptRotationToDeviceOrientation];
79-
}
80-
}
81-
if (value != nil) {
82-
_isLocked = true;
83-
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];
126+
if (@available(iOS 16.0, *)) {
127+
[self handleAboveEqualIos16WithOrientationMask:orientationMask viewController:vc result:result selector:selector];
128+
// always double check the supported interfaces, so we update if needed
129+
// but do it right at the end here to avoid the "double" rotation issue reported in
130+
// https://github.com/apache/cordova-plugin-screen-orientation/pull/107
131+
[self.viewController setNeedsUpdateOfSupportedInterfaceOrientations];
84132
} else {
85-
_isLocked = false;
133+
[self handleBelowEqualIos15WithOrientationMask:orientationMask viewController:vc result:result selector:selector];
86134
}
87135
}
88136

0 commit comments

Comments
 (0)