Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SDLLockScreenPresenter overrides native app's supportedInterfaceOrientations and shouldAutorotate properties #1250

Closed
SatbirTanda opened this issue Apr 26, 2019 · 6 comments
Labels
bug A defect in the library

Comments

@SatbirTanda
Copy link
Contributor

SatbirTanda commented Apr 26, 2019

Bug Report

If a developer wants to create an app that supports both portrait and landscape orientation for some (not all) of their view controllers (with SDL integrated), then they should expect their portrait only view controllers to stay the same even if the device is rotated. When SDLLockScreenPresenter is initialized, it creates a new UIWindow object that, for some reason, alters the properties of view controllers in otherUIWindow objects in the app to match that of it's rootViewController - including those view controllers that are in the native app's UIWindow object. This results in the status bar auto-rotating to conform to SDLScreenshotViewController's supportedInterfaceOrientations and shouldAutorotate properties.

Reproduction Steps
  1. Set the UIViewControllerBasedStatusBarAppearance property to YES in Info.plist of the app
        <key>UIViewControllerBasedStatusBarAppearance</key>
	<true/>
  1. Make sure your app supports Landscape left, landscape right, portrait (can be done in Target or Info.plist)
  2. Now, you should be able to choose (through your code) which view controllers will support which orientations.
  3. Thus if one view controller only wanted to support portrait, then override supportedInterfaceOrientations to return .portrait
  4. Create an SDLManager object and call its start method (in AppDelegate).
  5. Use app and rotate the device to landscape - you will see the status bar rotate even though the view controller supports portrait only
Expected Behavior

View controllers that only support the portrait orientation should not see the status bar rotate when the device rotates

Observed Behavior

View controllers that only support the portrait orientation do see the status bar rotate when the device rotates

OS & Version Information
  • iOS Version: 12.2
  • SDL iOS Version: 6.2.0
  • Testing Against: There is no need to connect the iOS device to a Head Unit
Test Case, Sample Code, and / or Example App

I've attached two example apps that display the bug, one that initializes its AppDelegate's window property in code, and the other that initializes via Storyboards.
StatusBarBug-Nibs.zip
StatusBarBug-StoryBoard.zip

@SatbirTanda
Copy link
Contributor Author

SatbirTanda commented Apr 26, 2019

In order to make sure the SDLScreenshotViewController doesn't override the properties of other view controllers, this code added to the class makes it conform to the native app's preferences and fixes the issue.

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    UIViewController *viewController = [UIApplication sharedApplication].windows[0].rootViewController;
    
    if (viewController) {
        return viewController.supportedInterfaceOrientations;
    }
    
    return super.supportedInterfaceOrientations;
}
 
- (BOOL)shouldAutorotate {
    UIViewController *viewController = [UIApplication sharedApplication].windows[0].rootViewController;
    
    if (viewController) {
        return viewController.shouldAutorotate;
    }
    
    return super.shouldAutorotate;
}

@SatbirTanda SatbirTanda changed the title SDLScreenshotViewController overrides native app's supportedInterfaceOrientations and shouldAutorotate properties SDLLockScreenPresenter overrides native app's supportedInterfaceOrientations and shouldAutorotate properties Apr 26, 2019
@SatbirTanda
Copy link
Contributor Author

SatbirTanda commented May 1, 2019

Also, an interesting note in th Apple docs regarding supportedInterfaceOrientations:

https://developer.apple.com/documentation/uikit/uiviewcontroller/1621435-supportedinterfaceorientations?language=objc and

When the user changes the device orientation, the system calls this method on the root view controller or the topmost presented view controller that fills the window. If the view controller supports the new orientation, the window and view controller are rotated to the new orientation. This method is only called if the view controller'��s shouldAutorotate method returns YES.

@joeljfischer joeljfischer added the bug A defect in the library label May 2, 2019
@joeljfischer
Copy link
Contributor

I don't think the code you gave will work in all cases. For example, if the root view controller is a UINavigationViewController or UITabViewController and only some of the presented views support autorotation, or if a modal view controller is presented and it doesn't support autorotation.

@joeljfischer
Copy link
Contributor

@SatbirTanda please check my PR #1252. Thank you for the detailed issue, reproduction steps, example projects, etc. It made fixing this bug much easier and faster!

@joeljfischer
Copy link
Contributor

joeljfischer commented May 2, 2019

Attached is an example project showing the fix including a fix for presented view controllers, which I did confirm was not fixed by the code given above. We have to traverse the root view controller to check for modally presented views and use their autorotation preferences if they exist.

Note that we do not need to check the navigation controller or tab bar controller because the autorotation preferences don't cascade that way. If they want to offer different autorotation preferences per tab bar tab or navigation controller child controller, they must do something to return the child controller's rotation preferences within the container controller. As such, we don't traverse those containers for their children.

@joeljfischer
Copy link
Contributor

StatusBar 3.zip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A defect in the library
Projects
None yet
Development

No branches or pull requests

3 participants