Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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. Hopefully it's just because I'm new to iOS development but I suspect this isn't possible in my case. 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. 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. In this class I've set shouldAutoRotate to 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. This is not what I want. I only want the rotation to be disabled for the view controller circled in the picture.

enter image description here

Thanks in advance!

like image 708
user2900772 Avatar asked Jan 19 '14 12:01

user2900772


2 Answers

Add your AppDelegate.h

@property (nonatomic , assign) bool blockRotation;

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:

In your AppDelegate.swift:

var blockRotation = false

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

In your viewController:

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

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    AppDelegate.shared.blockRotation = false
}
like image 96
Ozgur Sahin Avatar answered Sep 20 '22 14:09

Ozgur Sahin


Thanks to @ozgur for the fix which worked for me. 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:

In 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...

class LoginViewController: UIViewController, UITextFieldDelegate, UIApplicationDelegate {

and then create a reference to the AppDelegate...

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

In viewDidLoad, set 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):

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:

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!

Happy trails!

like image 26
AT3D Avatar answered Sep 20 '22 14:09

AT3D