In the iOS16 system, when the horizontal and vertical screen rotation occurs, at some point, interfaceOrientation=landspace, [UIScreen mainScreen].bounds, UIWindowScene.screen.bounds.size, keyWindow.bounds.size exception will occur
NSArray *array = [[[UIApplication sharedApplication] connectedScenes] allObjects];
UIWindowScene *ws = (UIWindowScene *)array[0];
NSLog(@"interfaceOrientation:%d",ws.interfaceOrientation);
NSLog(@"screen:%@,screen:%@,keywindow:%@",NSStringFromCGSize(ws.screen.bounds.size),NSStringFromCGSize([UIScreen mainScreen].bounds.size),NSStringFromCGSize(ws.keyWindow.bounds.size));
---------out
2022-08-25 16:32:04.536120+0800 app[2008:61285] interfaceOrientation:3
2022-08-25 16:32:04.536305+0800 app[2008:61285] screen:{375, 812},screen:{375, 812},keywindow:{812, 375}
(lldb)
The orientation is landscape, but [UIScreen mainScreen].bounds or UIWindowScene.screen.bounds.size is the value in the portrait state, and the value of keyWindow.bounds.size is the value in the landscape state.
Post
Replies
Boosts
Views
Activity
I know that the horizontal and vertical screen switching has changed in iOS16, [[UIDevice currentDevice] setValue:@(UIDeviceOrientationUnknown) forKey:@"orientation"] is replaced by [UIWindowScene requestGeometryUpdateWithPreferences].
However, the preferredInterfaceOrientationForPresentation method is outrageous in iOS16. In iOS16, if 'presentViewController:' + [UIWindowScene requestGeometryUpdateWithPreferences] goes to a ViewController, rewriting preferredInterfaceOrientationForPresentation in ViewController to return the orientation for the first presentation will not take effect.
For example,
first, the program supports horizontal and vertical screens, [vcA presentViewController:vcB animated:YES completion:nil] + [UIWindowScene requestGeometryUpdateWithPreferences:nil] + [vcB setNeedsUpdateOfSupportedInterfaceOrientations]. vcA is currently in portrait, you want BVc to be displayed in landscape for the first time, rewrite in BVc - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { return UIInterfaceOrientationLandscapeLeft; } + - (UIInterfaceOrientationMask)supportedInterfaceOrientations{ return UIInterfaceOrientationMaskAllButUpsideDown; }; screen, but it is normal in versions before iOS16.
First of all, my program supports Portrait, Left and Right
Customize an AViewCOntroller, AViewCOntroller supports orientation Portrait, Left, Right, click on the screen to create a BViewCOntroller object and rotate it to landscape.()
@interface AViewCOntroller ()
@end
@implementation AViewCOntroller
#pragma mark - life method
- (void)viewDidLoad{
[super viewDidLoad];
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskAllButUpsideDown;
}
#pragma mark - event method
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
BViewCOntroller *vc =[[BViewCOntroller alloc] init];
[self presentViewController:vc animated:YES completion:nil];
[self _dealOrientation:UIInterfaceOrientationMaskLandscapeLeft vc:vc];
}
- (void)_dealOrientation:(UIInterfaceOrientationMask)orientation vc:(UIViewController *)vc{
if (@available(iOS 16.0, *)) {
if (vc) {
NSArray *array = [[[UIApplication sharedApplication] connectedScenes] allObjects];
UIWindowScene *ws = (UIWindowScene *)array[0];
UIWindowSceneGeometryPreferencesIOS *geometryPreferences = [[UIWindowSceneGeometryPreferencesIOS alloc] init];
geometryPreferences.interfaceOrientations = orientation;
[ws requestGeometryUpdateWithPreferences:geometryPreferences
errorHandler:^(NSError * _Nonnull error) {
}];
[vc setNeedsUpdateOfSupportedInterfaceOrientations];
}
} else {
[[UIDevice currentDevice] setValue:@(UIDeviceOrientationUnknown) forKey:@"orientation"];
[[UIDevice currentDevice] setValue:@(orientation) forKey:@"orientation"];
}
}
@end
window.rootViewController = [[AViewCOntroller alloc] init]
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.rootViewController = [[AViewCOntroller alloc] init];
[self.window makeKeyAndVisible];
return YES;
}
Customize an BViewCOntroller,BViewCOntrollersupports orientation Portrait, Left, Right。Implemented the preferredInterfaceOrientationForPresentation method。
@interface BViewCOntroller : UIViewController
@end
@implementation BViewCOntroller
- (void)viewDidLoad { [super viewDidLoad]; }
- (UIInterfaceOrientationMask)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskAllButUpsideDown;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationLandscapeLeft;
}
@end
When the program is run at this time, the device orientation defaults to vertical screen, so the first time the AViewCOntroller interface is loaded is also vertical screen. At this time, click the screen to create a BViewCOntroller object. Result: Before iOS16, preferredInterfaceOrientationForPresentation took effect, and BViewCOntroller was displayed horizontally for the first time. In IOS16 Bate 6, preferredInterfaceOrientationForPresentation is invalid, and BViewCOntroller will be displayed vertically for the first time.
I know that the horizontal and vertical screen switching has changed in iOS16, [[UIDevice currentDevice] setValue:@(UIDeviceOrientationUnknown) forKey:@"orientation"] is replaced by [UIWindowScene requestGeometryUpdateWithPreferences].
However, the preferredInterfaceOrientationForPresentation method is outrageous in iOS16. In iOS16, if 'presentViewController:' + [UIWindowScene requestGeometryUpdateWithPreferences] goes to a ViewController, rewriting preferredInterfaceOrientationForPresentation in ViewController to return the orientation for the first presentation will not take effect.
For example, first, the program supports horizontal and vertical screens, [vcA presentViewController:vcB animated:YES completion:nil] + [UIWindowScene requestGeometryUpdateWithPreferences:nil] + [vcB setNeedsUpdateOfSupportedInterfaceOrientations]. vcA is currently in portrait, you want vcB to be displayed in landscape for the first time, rewrite in vcB - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { return UIInterfaceOrientationLandscapeLeft; } + - (UIInterfaceOrientationMask)supportedInterfaceOrientations{ return UIInterfaceOrientationMaskAllButUpsideDown; }; Vertical screen, but it is normal in versions before iOS16.