iOS 6 landscape and portrait orientation

Peter picture Peter · Sep 24, 2012 · Viewed 17.5k times · Source

I have a table with a big list of stuff that comes from a plist file and clicking each of them takes you to a new view, a xib.

I have 2 views inside that .xib, one for portrait and one for landscape

In my h file I have this:

IBOutlet UIView *portraitView;  
IBOutlet UIView *landscapeView;

@property (nonatomic, retain) IBOutlet UIView *portraitView;  
@property (nonatomic, retain) IBOutlet UIView *landscapeView;

In my m file this:

[super viewDidLoad];  
    // Do any additional setup after loading the view from its nib.

    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:@"UIDeviceOrientationDidChangeNotification" object:nil];

}

- (void) orientationChanged:(id)object
{
    UIInterfaceOrientation interfaceOrientation = [[object object] orientation];

if (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)  
    {  
        self.view = self.portraitView;  
    }  
    else
    {  
        self.view = self.landscapeView;  
    }  
}

- (void)viewDidUnload
{

    [super viewDidUnload];  
    // Release any retained subviews of the main view.  
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation   
{  
    if (UIInterfaceOrientationIsPortrait(interfaceOrientation)) {  

       self.view = portraitView;
    } else if (UIInterfaceOrientationIsLandscape(interfaceOrientation)) {

       self.view = landscapeView;  
    }  
    return YES;

}

@end

Everything was working perfectly in iOS 5, showing landscape or portrait when needed.

Now with the iOS 6 update everything is a mess.

If I am in the table (portrait) view and click one item, it shows correct in portrait, if I rotate to landscape, the view shows the correct view as well, BUT being in landscape, if I go back to the table and select another item, it shows the portrait view instead of the landscape.

If I do the same but starting landscape, it shows portrait.

So, now the orientation is not working for anything.

The same happens to my other views using storyboard. They are portrait and always showed like that, now they rotate, shrink everything and leave my app as trash.

1- How can I fix the .xib orientation thing ?
2- How can I fix the storyboard orientation ? (they were static, now everything rotates (no code at all))

Thanks.

Answer

Xavier Zeppetella picture Xavier Zeppetella · Oct 9, 2012

I think that I have a work around. It's ugly but it's working... With iOS6 Apple suggest now to use 2 differences XIB file to switch between portrait & landscape view.

But if you want to use the previous method allowed in iOS 5.0 by "switching" between 2 UIView IBOutlet, you can try my ugly working solution. The idea is to rotate the view according to the orientation.

1) In you viewDidLoad, subscribe to orientation notification:

- (void)viewDidLoad
{
    [super viewDidLoad];
    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:@"UIDeviceOrientationDidChangeNotification" object:nil];
 }

2) Add a method called by the notification:

-(void)orientationChanged:(NSNotification *)object{
    NSLog(@"orientation change");
    UIDeviceOrientation deviceOrientation = [[object object] orientation];
    if(deviceOrientation == UIInterfaceOrientationPortrait || deviceOrientation == UIInterfaceOrientationPortraitUpsideDown){
        self.view = self.potraitView;
        if(deviceOrientation ==UIInterfaceOrientationPortraitUpsideDown){
            NSLog(@"Changed Orientation To PortraitUpsideDown");
            [self portraitUpsideDownOrientation];
        }else{
            NSLog(@"Changed Orientation To Portrait");
            [self portraitOrientation];
        }
    }else{
        self.view = self.landscapeView;
        if(deviceOrientation ==UIInterfaceOrientationLandscapeLeft){
            NSLog(@"Changed Orientation To Landscape left");
            [self landscapeLeftOrientation];
        }else{
            NSLog(@"Changed Orientation To Landscape right");
            [self landscapeRightOrientation];
        }

    }
}

3) And finally, add rotation method for each orientation:

-(void)landscapeLeftOrientation{

    // Rotates the view.
    CGAffineTransform transform = CGAffineTransformMakeRotation(-(3.14159/2));
    self.view.transform = transform;
    // Repositions and resizes the view.
    CGRect contentRect = CGRectMake(0, 0, 480, 320);
    self.view.bounds = contentRect;
}
-(void)landscapeRightOrientation{

    // Rotates the view.
    CGAffineTransform transform = CGAffineTransformMakeRotation(3.14159/2);
    self.view.transform = transform;
    // Repositions and resizes the view.
    CGRect contentRect = CGRectMake(0, 0, 480, 320);
    self.view.bounds = contentRect;
}
-(void)portraitOrientation{

    // Rotates the view.
    CGAffineTransform transform = CGAffineTransformMakeRotation(0);
    self.view.transform = transform;
    // Repositions and resizes the view.
    CGRect contentRect = CGRectMake(0, 0, 320, 480);
    self.view.bounds = contentRect;
}
-(void)portraitUpsideDownOrientation{

    // Rotates the view.
    CGAffineTransform transform = CGAffineTransformMakeRotation(3.14159);
    self.view.transform = transform;
    // Repositions and resizes the view.
    CGRect contentRect = CGRectMake(0, 0, 320, 480);
    self.view.bounds = contentRect;
}

I suggest you to make a custom UIViewController class and inherit-ate from this class to save redundant code. If you want to support both solution for ios5 and ios6 you can use a #endif macro to include the both code in your controllers.

Cheers