当模态旋转时,防止UIViewController旋转

时间:2018-04-26 12:11:30

标签: ios rotation uideviceorientation

我的应用程序基本上只是一个肖像应用程序。所以什么都没有旋转。但没有一个例外。用户可以添加照片,当全屏查看这些照片时,应该允许此ViewController旋转。

所以我认为如果我的ViewController呈现supportedInterfaceOrientations返回.portraitshouldAutorotate返回false,那么这应该就足够了,以防止旋转?!?

事实证明,当我在显示全屏图像的同时旋转时,下面的一个也会旋转。

总结:

RootViewController永远不应该旋转 PresentedViewController可以旋转,但他的旋转不应该旋转RootViewController

有没有办法实现这个目标?

4 个答案:

答案 0 :(得分:0)

您可以像AppDelegate中一样提出例外:

//auto rotate
    func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        //landscape for perticular view controller
        let navigationController = window?.rootViewController as? UINavigationController
        if let activeController = navigationController?.visibleViewController {
            if activeController.isKind(of: VGVideoVC.self)  {//Pass your VC here
//                print("I have found my controller!")
                return UIInterfaceOrientationMask.all;
            }else{
                return UIInterfaceOrientationMask.portrait;
            }
        }else{
            return UIInterfaceOrientationMask.portrait;
        }
    }

在VC的其他部分,你想要它强有力的肖像,你可以像这样使用:

//MARK:- Screen Orientation

override var supportedInterfaceOrientations: UIInterfaceOrientationMask{
    return .portrait
}

override var shouldAutorotate: Bool{
    return true
}

希望这有帮助。

答案 1 :(得分:0)

我想说禁用完整应用的方向更改并在照片视图控制器中聆听设备方向更改,并在设备方向更改时更新photosVC的用户界面。

这样的事情:

1

}

小心颠倒和其他你不需要的方向。

答案 2 :(得分:0)

请尝试以下代码。我跟着This tutorial,它对我有用。发生了什么:

步骤1.假设在General内,您的Device Orientation仅设为Portrait

步骤2.您在AppDelegate内添加的代码循环通过导航控制器,然后查看其顶视图控制器。如果这些vcs中的任何一个具有名称为canRotate的函数,则该特定vc将通过返回:return .allButUpsideDown

来更改步骤1中的设备方向。

将这两个功能添加到AppDelegate

的底部
// add this first function
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {

    // if the navigationController's root vc has a function inside of it named canRotate
    if let rootViewController = self.topViewControllerWithRootViewController(rootViewController: window?.rootViewController) {

        if (rootViewController.responds(to: Selector(("canRotate")))) {
            // Unlock landscape view orientations for this view controller
            return .allButUpsideDown;
        }
    }

    // Only allow portrait (standard behaviour). vcs that don't contain a function with the name "canRotate" can't rotate and stay in portrait only
    return .portrait;
}

// add this second function
// loop through tabBarController or any navigationControllers
private func topViewControllerWithRootViewController(rootViewController: UIViewController!) -> UIViewController? {
    if (rootViewController == nil) { return nil }
    if (rootViewController.isKind(of: UITabBarController.self)) {
        return topViewControllerWithRootViewController(rootViewController: (rootViewController as! UITabBarController).selectedViewController)
    } else if (rootViewController.isKind(of: UINavigationController.self)) {
        return topViewControllerWithRootViewController(rootViewController: (rootViewController as! UINavigationController).visibleViewController)
    } else if (rootViewController.presentedViewController != nil) {
        return topViewControllerWithRootViewController(rootViewController: rootViewController.presentedViewController)
    }
    return rootViewController
}

步骤3.在模态vc中,您应该添加一个名为@objc func canRotate(){}的函数。你不必在任何地方调用它或在它的花括号内添加任何东西。步骤2中的代码正在查找名为canRotate的此函数。如果其他vcs不包含具有该名称的函数,则它们无法旋转。

在你要旋转的模态viewController中,在viewDidLoad和viewWillDisappear之外的任何地方添加canRotate()函数,添加代码,将所有内容设置回常规的Portrait:

override func viewDidLoad() {
        super.viewDidLoad()
}

@objc func canRotate(){}

override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)

        // add this so once leaving this vc everything will go back to Portrait only
        if (self.isMovingFromParentViewController) {
            UIDevice.current.setValue(Int(UIInterfaceOrientation.portrait.rawValue), forKey: "orientation")
        }
}

答案 3 :(得分:0)

可能为时已晚,但是如果有人遇到同样的问题,我会提供解决方案。 如果为显示的控制器设置modalPresentationStyle = .fullScreen,则实际上可以抑制基础窗口的旋转,然后如果您查看“ View UI Hierarchy”,那么您会注意到代表全屏控制器的控制器将从控制器层次结构中删除。但是同时modalPresentationStyle = .overFullScreen将所有内容保持原样,即使默认情况下,旋转底层控制器也将其设置为纵向,这导致旋转的底层控制器,即,在modalPresentationStyle =的情况下,管理和路由系统事件的UIWindow在最高层控制器方面设置.overFullScreen。因此,根据事实,是否有必要自定义演示,我建议使用其他UIWindow,它将负责全屏演示控制器。 我已经为该解决方案实施了测试项目:here