iOS 6 device orientation issue
Asked Answered
L

3

7

I have 2 view controllers. I want 1st viewcontroller to be Portrait mode only while 2nd viewController should support all orientations. Please help me.

In AppDelegate class, my code is :

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];

    self.viewController = [[[ViewController alloc] initWithNibName:@"ViewController" bundle:nil] autorelease];
    UINavigationController * navController = [[UINavigationController alloc] initWithRootViewController:self.viewController];
    self.window.rootViewController = self.viewController;
  //  [self.window addSubview:navController.view];
    [self.window makeKeyAndVisible];   
    return YES;
}
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
    NSLog(@"supportedInterfaceOrientationsForWindow");
    return  UIInterfaceOrientationMaskAllButUpsideDown;
}

1st ViewController code is:

-(BOOL)shouldAutorotate
{
    return NO;
}


-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}
// Tell the system which initial orientation we want to have
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationMaskPortrait;
}

2nd ViewController code is:

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAllButUpsideDown;
}

-(BOOL)shouldAutorotate
{
    return YES;
}

// Tell the system which initial orientation we want to have
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationMaskAllButUpsideDown;
}

What i inspect is 'shouldAutorotate' method is not called for 1st and 2nd ViewController.

Your quick help will highly be appreciable. Thanks. Kashif

Lonesome answered 20/9, 2012 at 7:37 Comment(0)
A
8

Try to set supportedInterfaceOrientations for 2nd UIViewController like this:

- (BOOL) shouldAutorotate
{
    return YES;
}

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskLandscapeRight; // add any other you want
}

Also, enable only portrait in same method in 1st UIViewController.

Maybe you need to enable those orientations also in project settings which 2nd UIViewController needs to support.


[edit #1: Added sample application]

Here you go sample application which solves your problem, hopefully.

AppDelegate.h

#import <UIKit/UIKit.h>

@class FirstViewController;

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@property (strong, nonatomic) FirstViewController *viewController;

@end

AppDelegate.m

#import "AppDelegate.h"

#import "FirstViewController.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.viewController = [[FirstViewController alloc] initWithNibName:@"FirstViewController" bundle:nil];
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application
{
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

@end

FirstViewController.h

#import <UIKit/UIKit.h>

@interface FirstViewController : UIViewController

- (IBAction)goToSecondViewController:(id)sender;

@end

FirstViewController.m

#import "FirstViewController.h"
#import "SecondViewController.h"

@interface FirstViewController ()

@end

@implementation FirstViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

    if (self)
    {
        // Custom initialization
    }

    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

-(BOOL)shouldAutorotate
{
    return NO;
}

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAll;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationMaskPortrait;
}

- (IBAction)goToSecondViewController:(id)sender
{
    SecondViewController *svc = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil];
    [self presentViewController:svc animated:NO completion:nil];
}

@end

SecondViewController.h

#import <UIKit/UIKit.h>

@interface SecondViewController : UIViewController

- (IBAction)goToFirstViewController:(id)sender;

@end

SecondViewController.m

#import "SecondViewController.h"

@interface SecondViewController ()

@end

@implementation SecondViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

    if (self)
    {
        // Custom initialization
    }

    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAll;
}

-(BOOL)shouldAutorotate
{
    return YES;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationLandscapeLeft;
}

- (IBAction)goToFirstViewController:(id)sender
{
    [self dismissViewControllerAnimated:NO completion:nil];
}

@end

FirstViewController.xib

FirstViewController.xib

SecondViewController.xib

SecondViewController.xib

Atomize answered 20/9, 2012 at 7:48 Comment(10)
I have Portrait, Landscape left and Landscape rigth orientation setting in project info.plist file. I have also posted my code, please help me out.Lonesome
Okay. You should return UIInterfaceOrientationMaskPortrait from supportedInterfaceOrientations method in class which owns your 1st UIViewController and UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskLandscapeLeft from the same method in class which owns 2nd UIViewController.Atomize
Also, check in Interface Builder when you click on xib file you made for 2nd UIViewController that it's orientation is set to Landscape.Atomize
Owner of 1st viewController is NavControllerViewController.so according to you i have placed UIInterfaceOrientationMaskPortrait in supportedInterfaceOrientations method. Similarly, owner of 2nd viewController is 1st ViewController. I have now placed UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskLandscapeLeft in 1st view controller. But no success.Lonesome
I have made edit #1 to my answer. Try that and let me know if it worked for you.Atomize
Hi, i tried your #1 solution, but its still rotating. I also want my viewcontroller to just stay in portrait orientation.Vimineous
What is still rotating? In my example I just made 1st UIViewController stays only in Portrait mode and 2nd UIViewController can be rotated in any direction. When I run this application, 1st UIViewController is ONLY in Portrait mode. 2nd UIViewController can rotate in any direction, but it's just implementation. You can limit it to the directions you want.Atomize
@uerceg, you solution is fine because you are "Presenting" 2nd Viewcontroller. But if we gonna 'Push' 2nd view controller then expected behaviour is not acheived. I want to 'Pushed' my 2nd viewcontroller, not 'Present' please help in this regard.Lonesome
Or in other words, if i change your code from : - (IBAction)goToSecondViewController:(id)sender { SecondViewController *svc = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil]; [self presentViewController:svc animated:NO completion:nil]; } to - (IBAction)goToSecondViewController:(id)sender { SecondViewController *svc = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil]; [self pushViewController:svc animated:NO]; } then you will experience the same wrong output as i am experiencing.Lonesome
from your code orientation is successful changing but unable to change the frame. Can you please tell me where I am lagging behindAkee
F
2

As per your description , first view controller pushed into navigation controller. Your method definition of shouldAutorotate and supportedInterfaceOrientations are absolutely correct. During orientation changes, your navigation Controller's shouldRotate only fired and won't fired your first view controller's(child of nav controller) shouldAutorotate. So you have to category navigationController in your view controller or in seperate file and import into it wherever needed. Code as below for UINavigation Controller category.

.h file have this code

    @interface UINavigationController (autoRotate)

-(BOOL)shouldAutorotate;
- (NSUInteger)supportedInterfaceOrientations;

@end

.m file have this code

  #import "UINavigationController+autoRotate.h"

@implementation UINavigationController (autoRotate)

-(BOOL)shouldAutorotate
{
    return [[self.viewControllers lastObject] shouldAutorotate];
}

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

If you write category in separate file, you have to import .h file in your first and second view controllers as #import "UINavigationController+autoRotate"

Faubert answered 29/3, 2013 at 6:36 Comment(0)
B
0

a simple solution:

implement : - (NSUInteger)supportedInterfaceOrientations

when asked from AppDelegate.m

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window

for more detail already answered here: iOS 6 landscape and portrait orientation

Burford answered 5/2, 2013 at 9:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.