2

I am have trouble trying to update our app from relying on "shouldAutorotate". We are using Objective C.

Currently, in iOS15, the "shouldAutorotate" updates the location and size of some items in the current view depending on the orientation of the device.

However, in iOS16, shouldAutorotate is deprecated. I have reviewed the docs, but I am soooo confused, can anyone help? Any examples on how to implement this???

jsdigital
  • 21
  • 2
  • Do you have a static set of rotations that are supported application-wide, or do you need custom allowed rotations per view controller? – danielbeard Oct 05 '22 at 21:49
  • Each viewcontroller has it's own shouldAutorotate. In the main viewcontroller, the shouldAutorotate has specific settings for elements in the main view depending on the orientation of the device. – jsdigital Oct 06 '22 at 01:52
  • Have a look at [viewWillTransitionToSize](https://developer.apple.com/documentation/uikit/uicontentcontainer/1621466-viewwilltransitiontosize?language=objc) – Ptit Xav Oct 06 '22 at 09:27
  • I tried that, but the problem is it is called even when another view controller is showing. – jsdigital Oct 06 '22 at 10:35
  • I wanted to thank you all for your help, I think I finally figured it out. I will be posting an answer (that works for me) and some code to help others. – jsdigital Oct 07 '22 at 17:09
  • Arg. My requirement is that the app needs to stay in the orientation that the device was in when the layout was called. IE, I have to lock orientation down to what it currently is. – VTPete Nov 14 '22 at 20:12
  • @jsdigital I'm curious what ended up working for you – pohl Nov 30 '22 at 22:07
  • For that particular app, I made a work around using the setNeedsUpdateOfSupportedInterfaceOrientation. I put the code from my ShouldAutorotate into the setNeedsUpdateOfSupportedInterfaceOrientation. I added an observer(UiDeviceOrientationDidChange) , in the viewwillappear, which called the setNeedsUpdateOfSupportedInterfaceOrientation. Important, if you add this observer, make sure you remove it in the viewDidDisappear. Hope this info is helpful! – jsdigital Dec 02 '22 at 16:42

1 Answers1

0

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.

Ecuador
  • 1,014
  • 9
  • 26