简体   繁体   English

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

[英]Disable rotation for View Controller in Navigation Controller

First of all, this isn't a duplicate. 首先,这不是重复的。 I've looked at all of the questions related to this on SO and none of them work for me. 我已经在SO上查看了与此相关的所有问题,但没有一个对我有用。 Hopefully it's just because I'm new to iOS development but I suspect this isn't possible in my case. 希望这只是因为我是iOS开发的新手,但我怀疑这对我而言不可能。 I've attached a picture with the view controller circled that I want to disable rotation for. 我已在带有圆圈的视图控制器上附加了一张我想对其禁用旋转的图片。

I've already tried: Subclassing the view controller that I want to disable rotation for and using the shouldAutoRotate method by setting it to NO. 我已经尝试过:将要为其禁用旋转的视图控制器子类化,并通过将shouldAutoRotate方法设置为NO来使用它。 Apparently this doesn't work because it's the navigation controller that dictates whether its view controllers can rotate. 显然,这是行不通的,因为导航控制器决定了其视图控制器是否可以旋转。 So, I subclassed UINavigationController and used this class in storyboard instead of the default navigation controller. 因此,我UINavigationController子类,并在情节UINavigationController使用了此类而不是默认的导航控制器。 In this class I've set shouldAutoRotate to NO. 在这个类中,我将shouldAutoRotate设置为NO。 It still doesn't work. 它仍然不起作用。 Don't really know what I'm doing wrong. 真的不知道我在做什么错。

When I extend the root view controller with my view controller class with shouldAutoRotate set to NO, it disables rotation...for the whole app. 当我将我的视图控制器类的shouldAutoRotate设置为NO扩展根视图控制器时,它将禁用整个应用程序的旋转。 This is not what I want. 这不是我想要的。 I only want the rotation to be disabled for the view controller circled in the picture. 我只希望图片中圈出的视图控制器禁用旋转。

在此处输入图片说明

Thanks in advance! 提前致谢!

Add your AppDelegate.h 添加您的AppDelegate.h

@property (nonatomic , assign) bool blockRotation;

AppDelegate.m AppDelegate.m

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

In view Controller that you want to disable rotation 在视图控制器中要禁用旋转

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

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

  }

Swift 4.2 and later: Swift 4.2及更高版本:

In your AppDelegate.swift: 在您的AppDelegate.swift中:

var blockRotation = false

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

In your viewController: 在您的viewController中:

override func viewDidLoad() {
    super.viewDidLoad()
    AppDelegate.shared.blockRotation = true
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    AppDelegate.shared.blockRotation = false
}

Thanks to @ozgur for the fix which worked for me. 感谢@ozgur为我工作的修复程序。 I would 'vote up', but apparently I'm not good enough (whatever!) to vote whether a fix works or not. 我会“投票赞成”,但显然我不够好(无论如何!)都不能投票决定修复程序是否有效。 Anyway, here it is in Swift: 无论如何,这是在Swift中:

In AppDelegate.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)
    }
}

In the ViewController that you want to block rotation, add UIApplicationDelegate to your class... 在要阻止旋转的ViewController中,将UIApplicationDelegate添加到您的类中。

class LoginViewController: UIViewController, UITextFieldDelegate, UIApplicationDelegate {

and then create a reference to the AppDelegate... 然后创建对AppDelegate的引用...

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

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

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.

    appDelegate.blockRotation = true

}

In viewWillAppear, set the orientation to force the device to the chosen orientation (Portrait in this example): 在viewWillAppear中,设置方向以将设备强制为选定的方向(在此示例中为纵向):

override func viewWillAppear(animated: Bool) {

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

}

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

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

This worked for me in this exact (multiple view controllers in a Navigation Controller) scenario, after many hours of reading other solutions on this site. 在经过数小时的阅读本网站上的其他解决方案之后,在这种精确的情况下(导航控制器中有多个视图控制器),这对我有用。 Thanks again to @ ozgur - I'd up-vote your answer if I could! 再次感谢@ ozgur-如果可以的话,我会投票赞成你的答案

Happy trails! 快乐的足迹!

For those of you using Swift 2, you can follow Andre's answer, but in step one, use the code below in your AppDelegate.swift: 对于使用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: now returns a UIInterfaceOrientationMask instead of an Int. supportedInterfaceOrientationsForWindow:现在返回UIInterfaceOrientationMask而不是Int。

You have to check in your root view controller is rotation allowed in current top controller and return YES or NO in supportedInterfaceOrientations method. 您必须在根视图控制器中检查当前顶部控制器中是否允许旋转,并在supportedInterfaceOrientations方法中返回YES或NO。 So it should be like the following code in your root controller ( adapt the code to your case ): 因此,它应该类似于您的根控制器中的以下代码( 使代码适合您的情况 ):

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

Then in each view controller add supported interface orientations, for example: 然后在每个视图控制器中添加支持的界面方向,例如:

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

My case has 3 view controller: 我的案例有3个视图控制器:
- first view controller: portrait -第一视角控制器:人像
- second view controller: landscape right (has navigation controller and was presented by first view controller) -第二个视图控制器:横向权限(具有导航控制器,由第一个视图控制器提供)
- third view controller: portrait (has navigation controller and was pushed by second view controller ) -第三视图控制器:人像(具有导航控制器,并由第二视图控制器推动)
And this is my solution in swift 3: 这是我迅速解决的办法3:
------------------------------------ ------------------------------------
At AppDelegate : AppDelegate
- Add this property to save your setting -添加此属性以保存您的设置

private var orientation: UIInterfaceOrientationMask = .portrait

-Then create a function to set rotate for your device: -然后创建一个函数来设置设备的旋转角度:

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")
}

- Finally, implement support orientation method: -最后,实现支持定位方法:

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

-------------------------------- --------------------------------
Then you can call like this before display destination view controller 然后您可以在显示目标视图控制器之前像这样调用

(UIApplication.shared.delegate as! AppDelegate).rotateScreen(orientation: .landscapeRight)

For example, in my case: When user tap on button at the First to present the Second, I'll do like this 例如,在我的情况下:当用户在“第一个”上点击按钮以显示第二个时,我会这样做

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

And the close button at the Second I'll do like this 第二秒的关闭按钮我会这样

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

That's all! 就这样! You could never mind using navigation controller or not. 不用介意使用导航控制器。 Hope this helps you guys ^__^! 希望这对你们有所帮助^ __ ^!

UINavigationController+Rotation Category UINavigationController +旋转类别

When u usign navigation controller SupportedInterfaceOrientaions of ViewController will not work adding this category to ur Project will get the response from your viewController also instead of NavigationController alone. 当您使用导航控制器的ViewController SupportedInterfaceOrientaions无法正常工作时,将此类别添加到您的项目中,Project也会从您的viewController中获得响应,而不是单独从NavigationController获得响应。

In my case I have the view controller embedded in a navigation controller, and most of the solutions don't work because the viewcontroller depends on the navigation controller orientation. 在我的情况下,我将视图控制器嵌入到导航控制器中,并且大多数解决方案都不起作用,因为视图控制器取决于导航控制器的方向。 For this when you create the instance of the view controller you have to cast it to UINavigationController : 为此,在创建视图控制器的实例时,必须将其强制转换为UINavigationController:

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

And then add this extension: extension PlaySplashViewController: UINavigationControllerDelegate { 然后添加以下扩展名:扩展名PlaySplashViewController:UINavigationControllerDelegate {

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

} }

In this case this going to set portrait orientation for the navigation controller so the view controller going to use this orientation too. 在这种情况下,这将为导航控制器设置纵向方向,因此视图控制器也将使用此方向。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM