How to force view controller orientation in iOS 8?

前端 未结 25 2085
太阳男子
太阳男子 2020-11-22 13:11

Before iOS 8, we used below code in conjunction with supportedInterfaceOrientations and shouldAutoRotate delegate methods to force app orie

相关标签:
25条回答
  • 2020-11-22 13:13

    The top solution above:

    let value = UIInterfaceOrientation.LandscapeLeft.rawValue
    UIDevice.currentDevice().setValue(value, forKey: "orientation")
    

    didnt'work for me when I called it in viewDidAppear of the presented view controller. However it did work when I called it in preparForSegue in the presenting view controller.

    (Sorry, not enough reputation points to comment on that solution, so I had to add it like this)

    0 讨论(0)
  • 2020-11-22 13:18
    - (void)viewDidAppear:(BOOL)animated
    {
        [super viewDidAppear:animated];
        [UIViewController attemptRotationToDeviceOrientation];
    }
    
    0 讨论(0)
  • 2020-11-22 13:19

    I have the same problem and waste so many time for it. So now I have my solution. My app setting is just support portrait only.However, some screens into my app need have landscape only.I fix it by have a variable isShouldRotate at AppDelegate. And the function at AppDelegate:

    func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> Int {
        if isShouldRotate == true {
            return Int(UIInterfaceOrientationMask.Landscape.rawValue)
        }
        return Int(UIInterfaceOrientationMask.Portrait.rawValue)
    }
    

    And finally when a ViewControllerA need landscape state. Just do that: before push/present to ViewControllerA assign isShouldRotate to true. Don't forget when pop/dismiss that controller assign isShouldRotate to false at viewWillDisappear.

    0 讨论(0)
  • 2020-11-22 13:20

    For iOS 7 - 10:

    Objective-C:

    [[UIDevice currentDevice] setValue:@(UIInterfaceOrientationLandscapeLeft) forKey:@"orientation"];
    [UINavigationController attemptRotationToDeviceOrientation];
    

    Swift 3:

    let value = UIInterfaceOrientation.landscapeLeft.rawValue
    UIDevice.current.setValue(value, forKey: "orientation")
    UINavigationController.attemptRotationToDeviceOrientation()
    

    Just call it in - viewDidAppear: of the presented view controller.

    0 讨论(0)
  • 2020-11-22 13:20

    My requirements are

    1. lock all views in portrait mode
    2. use AVPlayerViewController to play video

    When video is playing, if it's a landscape then allow the screen to rotate landscape right and landscape left. If it's a portrait then lock the view in portrait mode only.

    First, define supportedInterfaceOrientationsForWindow in AppDelegate.swift

    var portrait = true
    func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
        if portrait {
            return .Portrait
        } else {
            return .Landscape
        }
    }
    

    Second, in your main view controller, define following functions

    override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
        print("\(#function)")
        return .Portrait
    }
    
    override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
        return .Portrait
    }
    
    override func shouldAutorotate() -> Bool {
        return false
    }
    

    Then, you need to subclass AVPlayerViewController

    class MyPlayerViewController: AVPlayerViewController {
    
        var size: CGSize?
    
        var supportedOrientationMask: UIInterfaceOrientationMask?
        var preferredOrientation: UIInterfaceOrientation?
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            if let size = size {
                if size.width > size.height {
                    self.supportedOrientationMask =[.LandscapeLeft,.LandscapeRight]
                    self.preferredOrientation =.LandscapeRight
                } else {
                    self.supportedOrientationMask =.Portrait
                    self.preferredOrientation =.Portrait
                }
            }
        }
    

    Override these three functions in MyPlayerViewController.swift

    override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
        return self.supportedOrientationMask!
    }
    
    override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
        return self.preferredOrientation!
    }
    

    Because user might rotate device landscape left or landscape right, we need to set auto rotate to be true

    override func shouldAutorotate() -> Bool {
        return true
    }
    

    Finally, create MyPlayerViewController instance in your view controller and set the property size value.

    let playerViewController = MyPlayerViewController()
    
    // Get the thumbnail  
    let thumbnail = MyAlbumFileManager.sharedManager().getThumbnailFromMyVideoMedia(......)
    
    let size = thumbnail?.size
    playerViewController.size = size
    

    Initiate your player with proper videoUrl, then assign your player to playerViewController. Happy coding!

    0 讨论(0)
  • 2020-11-22 13:20

    There still seems to be some debate about how best to accomplish this task, so I thought I'd share my (working) approach. Add the following code in your UIViewController implementation:

    - (void) viewWillAppear:(BOOL)animated
    {
        [UIViewController attemptRotationToDeviceOrientation];
    }
    
    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
    {
        return (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft);
    }
    
    -(BOOL)shouldAutorotate
    {
        return NO;
    }
    
    - (UIInterfaceOrientationMask)supportedInterfaceOrientations
    {
        return UIInterfaceOrientationMaskLandscapeLeft;
    }
    

    For this example, you will also need to set your allowed device orientations to 'Landscape Left' in your project settings (or directly in info.plist). Just change the specific orientation you want to force if you want something other than LandscapeLeft.

    The key for me was the attemptRotationToDeviceOrientation call in viewWillAppear - without that the view would not properly rotate without physically rotating the device.

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