0

I realize there are a few threads regarding this issue. However, I am new to this, and some of the solutions I found did not work for me.

I have an iPhone app that should support all orientations except in one view. This view I would like to lock in portrait only. I tried this code, but it still goes to landscape mode when I flip the phone... what am I doing wrong?

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

- (BOOL)shouldAutorotate
{
    return NO;
}

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}
Doc Brown
  • 45
  • 1
  • 6

4 Answers4

0

Note: shouldAutorotateToInterfaceOrientation has been deprecated in iOS 6.0.

You should now override the supportedInterfaceOrientation and preferredInterfaceOrientationForPresentation classes.

Like so:

- (NSUInteger) supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

- (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationPortrait;
}
Drewness
  • 5,004
  • 4
  • 32
  • 50
  • I tried the code above, but the view still goes to landscape mode when I flip the phone... is there anything else I need to do? Thanks! – Doc Brown Feb 28 '14 at 20:44
  • Did you remove the `shouldAutorotateToInterfaceOrientation` class from your code? – Drewness Feb 28 '14 at 20:50
  • 1
    I found the answer at http://stackoverflow.com/questions/12520030/how-to-force-a-uiviewcontroller-to-portait-orientation-in-ios-6/12522119#12522119 – Doc Brown Feb 28 '14 at 21:00
  • +1 - Funny, I was just reading through this post when you added your comment. It's meant to be! – Drewness Feb 28 '14 at 21:02
0

The bottom line is that if you're using a UINavigationController, it will not normally forward the supportedInterfaceOrientations call to the top view controller. Subclass UINavigationController and add:

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

seems to be the cleanest answer. There are other approaches that involve putting the code in your app delegate, using categories to add the code to UINavigationController, etc., but this seems the cleanest solution to me.

David Berry
  • 40,941
  • 12
  • 84
  • 95
  • Thank you for your answer. I tried the code, but I got an error message, stating "Property topViewController not found..." – Doc Brown Feb 28 '14 at 20:48
  • You need to put this code into a UINavigationController subclass and then make sure that your storyboard references the subclass. – David Berry Feb 28 '14 at 21:16
0

You must lock the controller in your RootViewController(eg.UITabbarController or UINavigationController) . When your device rotate,First It will call AppDelegate's rotateMethod(eg.- (BOOL)shouldAutorotate , - (NSUInteger)supportedInterfaceOrientations).Then It call RootViewController's RotateMehod.

1.If your RootViewController is UITabbarController, add code like following code in your UITabbarController(NotRotateController is the controller your do not want go to landscape mode )

#import "NotRotateController.h"
- (BOOL)shouldAutorotate
{
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
    UINavigationController * baseNavCtr = self.viewControllers[self.selectedIndex];
    if ([baseNavCtr.topViewController isKindOfClass:[NotRotateController class]]) {
        return UIInterfaceOrientationMaskPortrait;
    }else {
        return UIInterfaceOrientationMaskAllButUpsideDown;
    }
}

2.If your RootViewController is UINavigationContoller

#import "NotRotateController.h"

- (NSUInteger)supportedInterfaceOrientations
{
    if (self.topViewController isKindOfClass:[NotRotateController class]) {
        return UIInterfaceOrientationMaskPortrait;
    }else {
        return UIInterfaceOrientationMaskAllButUpsideDown;
    }
}

- (BOOL)shouldAutorotate {
    return YES;
}

3.Summarize, judge your the Controller in RootViewController' - (NSUInteger)supportedInterfaceOrientations method ,return the orientation your want to surport

Slemon
  • 791
  • 7
  • 12
0

try this:

1- Add these 2 functions to App Delegate. Read the comments for more information

class AppDelegate: UIResponder, UIApplicationDelegate {

    // 1.
    func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {

        if let rootViewController = self.topViewControllerWithRootViewController(rootViewController: window?.rootViewController) {

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

            // *** THIS WILL GET CALLED WHEN THE VC CALLS THIS SELECTOR ***
            if (rootViewController.responds(to: Selector(("cantRotate")))) {
                // Unlock portrait only view orientation for this view controller
                return .portrait
            }
        }

        // Allow all orientations but upside down
        return .allButUpsideDown
    }

    // 2.
    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
    }
}

2- Add this to the vc you want to be Portrait only:

class YourViewController: UIViewController {

    // MARK: - Portrait Only. The first function above inside App Delegate responds to this
    @objc func cantRotate() {}
}
Lance Samaria
  • 17,576
  • 18
  • 108
  • 256