I will first answer to the title question, since that's how I came across this post. So, I have an app where only some of the ViewControllers need to stick to the orientation you launch them in while they are displayed. This used to work simply by having:
-(BOOL)shouldAutorotate {
return NO;
}
So, for iOS 16 I had to first get the launch orientation on loadView:
if (@available(iOS 16.0, *)) {
UIWindowScene *activeWindow = (UIWindowScene *)[[[UIApplication sharedApplication] windows] firstObject];
initOrientation = [activeWindow interfaceOrientation] ?: UIInterfaceOrientationPortrait;
}
Then allow only that specific orientation:
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
if (initOrientation == UIInterfaceOrientationPortrait)
return UIInterfaceOrientationMaskPortrait;
if (initOrientation == UIInterfaceOrientationPortraitUpsideDown)
return UIInterfaceOrientationMaskPortraitUpsideDown;
if (initOrientation == UIInterfaceOrientationLandscapeLeft)
return UIInterfaceOrientationMaskLandscapeLeft;
if (initOrientation == UIInterfaceOrientationLandscapeRight)
return UIInterfaceOrientationMaskLandscapeRight;
return UIInterfaceOrientationMaskAll;
}
Now, moving on to the OP's detailed question, I am pretty sure shouldAutorotate
was never the place to make layout and it would have always been bad practice to put such code in there. I mean, system code is doing expecting it to be a fast function returning a BOOL value and using it as such.
Instead, you can trigger orientation layout changes from:
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinator {
}
Or use layoutSubview
/viewWillLayoutSubviews
/viewDidLayoutSubviews
.