Search code examples
iosswiftuiviewcontrolleruikitscreen-orientation

Swift 5, lock first VC to Potrait mode, other VC support all orientations


I am trying to build an app in Swift 5 which has a locked VC in potrait mode. In the next VC i want the orientation to support all orientations. I have tried several different solutions and none of them seem to work. I don't have Navigation Controller or TabBar. My application is now locked in potrait on both VC:s. I do support different device orientations in the general settings tab.

This is my current code in AppDelegate:

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.all
}

First VC:

override var shouldAutorotate: Bool {
    return false
}

override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.portrait
}

override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
    return UIInterfaceOrientation.portrait
}

Second VC:

override var shouldAutorotate: Bool {
    return false
}

override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.all
}

Solution

  • This is unfortunately a tricky subject. But if you have no UINavigationController or UITabBarController it should be straightforward.

    In the AppDelegate, like you've already done, put:

    func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
      .all
    }
    

    In the first UIViewController set:

    // This stops the controller from rotating
    override var shouldAutorotate: Bool {
      false
    }
    
    // This will rotate it back to portrait once it's presented again
    override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
      .portrait
    }
    

    In the second one you don't need anything because shouldAutorotate defaults to true.

    NOTE: If you aren't using a UINavigationController you are probably presenting the second controller. The second controller has to have a modalPresentationStyle of either .fullScreen or .currentContext.

    I tried it in a sample project and it's the only way I got it to work.