how to lock portrait orientation for only main view using swift

后端 未结 16 1862
野性不改
野性不改 2020-12-07 13:38

I have created an application for iPhone, using swift, that is composed from many views embedded in a navigation controller. I would like to lock the main v

相关标签:
16条回答
  • 2020-12-07 14:05

    Here is the working code to lock the orientation:

    override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        if UIDevice.current.userInterfaceIdiom == .phone {
            return .allButUpsideDown
        } else {
            return .all
        }
    }
    

    More information:

    https://www.hackingwithswift.com/example-code/uikit/how-to-lock-a-view-controllers-orientation-using-supportedinterfaceorientations

    0 讨论(0)
  • 2020-12-07 14:06

    This is the syntax for Swift 3 (XCode 8.2 beta), where these methods where converted to properties:

    extension UINavigationController {
        override open var shouldAutorotate: Bool {
            return false
        }
    }
    
    class ViewController: UIViewController {
    
        /*
                ...
        */
    
        override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
            return UIInterfaceOrientationMask.portrait
        }
    }
    
    0 讨论(0)
  • 2020-12-07 14:08

    Update: if you're having trouble to set orientation right after the app launches in iOS 10, try do it in ObjC instead of Swift, and with class MyNavigationController: MyNavigationControllerBase:

    @implementation ABNavigationControllerBase
    - (NSUInteger)supportedInterfaceOrientations
    {
        return UIInterfaceOrientationMaskPortrait;
    }
    @end
    

    Swift 3:

    class MyNavigationController: UINavigationController {
        override func viewDidLoad() {
            super.viewDidLoad()
            UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
        }
        override var shouldAutorotate: Bool {
            return false
        }
        override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
            return .portrait
        }
        override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
            return .portrait
        }
    }
    
    0 讨论(0)
  • 2020-12-07 14:08

    Same JasonJasonJason answer in Swift 4.2+ (It worked correctly with iOS 11)

    1- Override shouldAutorotate and supportedInterfaceOrientations as shown below.

    extension UINavigationController {
    
    open override var shouldAutorotate: Bool {
        return true
    }
    
    open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return (visibleViewController?.supportedInterfaceOrientations)!
        }
    }
    

    2- And your main viewcontroller (portrait at all times), should have:

     public override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return UIInterfaceOrientationMask.portrait
    }
    

    3- Then, in your subviewcontrollers that you want to support portrait or landscape:

     public override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return UIInterfaceOrientationMask.all
    }
    
    0 讨论(0)
  • 2020-12-07 14:09

    In the main controller where you want portrait,

    - (void)viewWillAppear:(BOOL)animated
    {
        [super viewWillAppear:animated];
    
    self.orientation = UIInterfaceOrientationMaskPortrait;
    //Or self.orientation = UIInterfaceOrientationPortraitUpsideDown
    }
    

    and in subVC where you want Landscape use

      self.orientation =  UIInterfaceOrientationLandscapeLeft:
       self.orientation =  UIInterfaceOrientationLandscapeRight:
    

    or you can override this method

    - (NSUInteger)supportedInterfaceOrientations
    {
      return UIInterfaceOrientationMaskPortrait;
    } 
    

    This is how i would do it with Obj-c in iOS7, i think this code would work in iOS8 too

    0 讨论(0)
  • 2020-12-07 14:11

    This requires two things

    • Informing the controller of its support for rotation.
    • Enforcing rotation and then handing over responsibility to a controller that knows its support for rotation.

    Declare an extension on view controller that forces orientation to portrait.

    extension UIViewController {
    
      func forcePortrait() {
        UIView.setAnimationsEnabled(false)
        UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
        UIView.setAnimationsEnabled(true)
      }
    
    }
    

    Any view controller that is locked to portrait could inherit traits.

    class PortraitViewController: UIViewController {
    
      override open var supportedInterfaceOrientations: UIInterfaceOrientationMask { return .portrait }
      override open var shouldAutorotate: Bool { return false }
    
      override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        forcePortrait()
      }
    
    }
    

    Any view controller that is capable of rotating between portrait and landscape can inherit those traits.

    class LandscapeViewController: UIViewController {
    
      override open var supportedInterfaceOrientations: UIInterfaceOrientationMask { return [.landscape, .portrait]  }
      override open var shouldAutorotate: Bool { return true }
    
      override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        // if leaving for a portrait only screen, force portrait.
        // forcePortrait()
      }
    
    }
    

    If your landscape view controller is about to segue to a portrait locked screen. Be sure to lock the orientation just before leaving. Then rely on the portrait view controller to enforce its own lack of rotation.

    0 讨论(0)
提交回复
热议问题