禁用导航控制器中View Controller的旋转

时间:2014-01-19 12:12:21

标签: ios uinavigationcontroller rotation viewcontroller navigationcontroller

首先,这不是重复。我在SO上查看了与此相关的所有问题,但这些问题对我来说都不起作用。希望这只是因为我是iOS开发的新手,但我怀疑在我的情况下这是不可能的。我附上了一张带有视图控制器的图片,我想要禁用旋转。

我已经尝试过:将我要禁用旋转的视图控制器子类化,并使用shouldAutoRotate方法将其设置为NO。显然这不起作用,因为它是导航控制器,指示其视图控制器是否可以旋转。因此,我将UINavigationController子类化,并在故事板中使用此类而不是默认的导航控制器。在本课程中,我将shouldAutoRotate设置为NO。它仍然无法正常工作。不知道我做错了什么。

当我使用我的视图控制器类扩展根视图控制器并将shouldAutoRotate设置为NO时,它会禁用整个应用程序的旋转....这不是我想要的。我只希望为图片中圈出的视图控制器禁用旋转。

enter image description here

提前致谢!

7 个答案:

答案 0 :(得分:10)

添加AppDelegate.h

@property (nonatomic , assign) bool blockRotation;

AppDelegate.m

-(NSUInteger)application:(UIApplication *)application       supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if (self.blockRotation) {
    return UIInterfaceOrientationMaskPortrait;
}
return UIInterfaceOrientationMaskAll;
}

在视图控制器中,您要禁用旋转

- (void)viewDidLoad
{
 [super viewDidLoad];
    AppDelegate* shared=[UIApplication sharedApplication].delegate;
    shared.blockRotation=YES;
}

-(void)viewWillDisappear:(BOOL)animated{
  AppDelegate* shared=[UIApplication sharedApplication].delegate;
  shared.blockRotation=NO;

  }

答案 1 :(得分:5)

感谢@ozgur为我提供的修复程序。我会'投票',但显然我不够好(无论如何!)投票是否有效。无论如何,这里是Swift:

在AppDelegate.swift中:

class AppDelegate: UIResponder, UIApplicationDelegate {


var blockRotation: Bool = false

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> Int {

    if (self.blockRotation) {
        println("supportedInterfaceOrientations - PORTRAIT")
        return Int(UIInterfaceOrientationMask.Portrait.rawValue)
    } else {
        println("supportedInterfaceOrientations - ALL")
        return Int(UIInterfaceOrientationMask.All.rawValue)
    }
}

在要阻止旋转的ViewController中,将 UIApplicationDelegate 添加到您的班级......

class LoginViewController: UIViewController, UITextFieldDelegate, UIApplicationDelegate {

然后创建对AppDelegate的引用...

var appDelegate = UIApplication.sharedApplication().delegate as AppDelegate

在viewDidLoad中,设置appDelegate.blockRotation = true:

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.

    appDelegate.blockRotation = true

}

在viewWillAppear中,设置方向以强制设备进入所选方向(本例中为纵向):

override func viewWillAppear(animated: Bool) {

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

}

然后在viewWillDisappear或prepareForSegue中,设置appDelegate.blockRotation = false:

override func viewWillDisappear(animated: Bool) {
    appDelegate.blockRotation = false
}

在这个网站上阅读其他解决方案数小时之后,这对我来说非常适合我(导航控制器中的多视图控制器)场景。再次感谢@ ozgur - 如果可以,我会投票your answer

快乐的小道!

答案 2 :(得分:3)

对于那些使用Swift 2的人,您可以按照Andre的回答,但在第一步中,使用AppDelegate.swift中的以下代码:

class AppDelegate: UIResponder, UIApplicationDelegate {


var blockRotation: Bool = false

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {

    if (self.blockRotation) {
        print("supportedInterfaceOrientations - PORTRAIT")
        return UIInterfaceOrientationMask.Portrait
    } else {
        print("supportedInterfaceOrientations - ALL")
        return UIInterfaceOrientationMask.All
    }
}

supportedInterfaceOrientationsForWindow:现在返回UIInterfaceOrientationMask而不是Int。

答案 3 :(得分:2)

您必须检查您的根视图控制器是当前顶级控制器允许的旋转,并在 supportedInterfaceOrientations 方法中返回YES或NO。所以它应该像你的根控制器中的以下代码(使代码适应你的情况):

- (NSUInteger)supportedInterfaceOrientations
{    
    return [self.navigationController.topViewController supportedInterfaceOrientations];
}

然后在每个视图控制器中添加支持的接口方向,例如:

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

答案 4 :(得分:1)

我的案例有3个视图控制器:
- 第一视图控制器:肖像
- 第二视图控制器:横向右侧(具有导航控制器并由第一视图控制器呈现)
- 第三视图控制器:纵向(具有导航控制器并由第二视图控制器推动)
这是我在swift 3中的解决方案:
------------------------------------
AppDelegate
- 添加此属性以保存您的设置

private var orientation: UIInterfaceOrientationMask = .portrait

- 然后创建一个功能来为您的设备设置旋转:

func rotateScreen(orientation: UIInterfaceOrientationMask) {
    self.orientation = orientation
    var value = 0;
    if orientation == .landscapeRight {
        value = UIInterfaceOrientation.landscapeRight.rawValue
    }else {
        value = UIInterfaceOrientation.portrait.rawValue
    }
    UIDevice.current.setValue(value, forKey: "orientation")
}

- 最后,实施支持定位方法:

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

--------------------------------
然后你可以在显示目标视图控制器

之前调用
(UIApplication.shared.delegate as! AppDelegate).rotateScreen(orientation: .landscapeRight)

例如,在我的情况下:当用户点击第一个按钮时出现第二个,我会这样做

(UIApplication.shared.delegate as! AppDelegate).rotateScreen(orientation: .landscapeRight)
self.present(navigation, animated: true, completion: nil)

第二个关闭按钮我会这样做

(UIApplication.shared.delegate as! AppDelegate).rotateScreen(orientation: .portrait)
self.dismiss(animated: true, completion: nil)

这就是全部!您永远不会介意使用导航控制器。 希望这可以帮助你们^ __ ^!

答案 5 :(得分:0)

UINavigationController+Rotation Category

当您使用SupportedInterfaceOrientaions的导航控制器ViewController无法将此类别添加到您的项目时,您的viewController也会获得响应,而不仅仅是NavigationController

答案 6 :(得分:0)

在我的情况下,我将视图控制器嵌入到导航控制器中,并且大多数解决方案都无法使用,因为视图控制器取决于导航控制器的方向。为此,在创建视图控制器的实例时,必须将其强制转换为UINavigationController:

    let theViewController = UIViewController()
    if let navController = theViewController as? UINavigationController {
        navController.delegate = self
    }

然后添加此扩展名: 扩展PlaySplashViewController:UINavigationControllerDelegate {

func navigationControllerSupportedInterfaceOrientations(_ navigationController: UINavigationController) -> UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.portrait
}

}

在这种情况下,这将为导航控制器设置纵向方向,因此视图控制器也将使用此方向。