How to handle different orientations in iOS

ADDED:
You can access this project on github
ios6rotations


Sorry guys for asking the question about screen rotation in iOS 6 but this is really a pain in the ass..and I still can’t understand it completely – for some reason it behaves differently under certain circumstances.

  • Slow load time for custom UIView in Swift
  • Parse - Query after a specific row
  • grouping or bundling of notifications in iOS inbox style notification
  • How can i add a button to google maps marker info window on ios?
  • Why is my library not able to expand on the CocoaPods website?
  • can i debug ios app installed from ipa archive
  • I have the following simple hierarchy of views in my test app:

    What I’m trying to achieve is – to keep blue controller in landscape only and red one is only in portrait.

    I have a subclass of UINavigationController with such code inside:

    @implementation CustomNavController
    
    - (BOOL)shouldAutorotate
    {
        return [[self.viewControllers lastObject] shouldAutorotate];
    }
    
    - (NSUInteger)supportedInterfaceOrientations
    {
        return  [[self.viewControllers lastObject] supportedInterfaceOrientations];
    }
    
    - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
        return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
    }
    
    @end
    

    In my blue controller I implemented this:

    - (BOOL)shouldAutorotate {
        return YES;
    }
    
    - (NSUInteger)supportedInterfaceOrientations {
        return UIInterfaceOrientationMaskLandscape;
    }
    

    And in red controller this:

    - (BOOL)shouldAutorotate {
        return YES;
    }
    
    - (NSUInteger)supportedInterfaceOrientations {
        return UIInterfaceOrientationMaskPortrait;
    }
    

    Now I have the following behavior:

    1. App started in landscape (OK)
    2. When I press the button my red controller pushed in landscape too (this is not ok because it must be shown in Portrait)
    3. It successfully rotates to portrait but not backward to landscape
    4. If I leave the red controller in Portrait mode my blue controller (which is restricted to landscape) shows in Portrait mode.

    P.S.
    All my rotation methods(posted above) are getting called normally.(by the way why do these methods getting called so many times per screen transition – 5-6 times)

    - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation does not getting called with pushing

    All(except portraitUpsideDown) orientations are included in plist.

    The question is – how to force rotation to supported orientation in each controller?

    I suggest you to post here (as answers) any 100% working code to handle rotations in ios6 (for example if you have some for iPad with SplitController) – I’ll keep this question in favorites to have all in one place when I need to handle some specific situations. Cheers!

    ADDED:
    Please do not post this as answer from landscape to portrait I hope that there’
    s more elegant way to do it.

    6 Solutions Collect From Internet About “How to handle different orientations in iOS”

    Using -[UIDevice setOrientation:] is a private API, and will get your application rejected. See this question.

    What you ask is not possible using public API and is also not recommended from HIG standpoint. What is supported and you should implement, is modal presentation of the different view controllers with different supported interface orientation. This is why the default implementation of UINavigationController is to always rotate; it assumes all view controllers have the same supported interface orientations.

    Take for example video playback on iPhone. Open the video apps (that comes with iOS). The root view controller only supports portrait orientation. However, start a video, and a modal view controller pops up which only supports landscape interface orientations. This seems exactly the behavior you wish to achieve.

    This is why preferredInterfaceOrientationForPresentation is not called. preferredInterfaceOrientationForPresentation only gets called when using presentViewController:animated:.

    A small gotcha, if you require a navigation bar in each stage of your scene, you will need to enclose each modal view controller with a navigation controller. You can then pass the required data in prepareForSegue: by accessing topViewController of the navigation controller object in the segue.


    Here is an example project which behaves correctly according to your requirements (or at least will give you ideas how to implement):

    http://www.mediafire.com/?zw3qesn8w4v66hy

    My two cents worth.

    You can present an empty transparent modal view quickly then dismiss it, maybe on ViewDidLoad: or viewWillAppear: on your ViewController and ViewControllerSecond class as a quick workaround.

    Also, in storyboard, you can set ViewController class orientation to landscape visually.

    use this line for programmatically change orientation… work 100%

    [[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];
    

    and also when you add this line at that time one warning appear and for remove this warning just add bellow code on you implementation file.. at the top.

    @interface UIDevice (MyPrivateNameThatAppleWouldNeverUseGoesHere)
    - (void) setOrientation:(UIInterfaceOrientation)orientation;
    @end
    

    and after that in bellow method just write this code if required..

    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
    {
        // Return your supported orientations
    
     if (currentMainView==blueOne) {
            return toInterfaceOrientation== UIInterfaceOrientationPortrait;
        }
    }
    

    I have a similar situation in one of my apps (although do note that I am not using UINavigationController).

    Change the shouldAutorotate methods in both of your viewControllers:

    //in blue (landscape only)
    -(BOOL)shouldAutorotate{
        if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation)) {
            return YES;
        }
        else {
            return NO;
        }
    }
    
    //in red (portrait only)
    -(BOOL)shouldAutorotate{
        if (self.interfaceOrientation == UIInterfaceOrientationPortrait) {
            //note that UIInterfaceOrientationIsPortrait(self.interfaceOrientation) will return yes for UIInterfaceOrientationPortraitUpsideDown
            return YES;
        }
        else {
            return NO;
        }
    }
    

    Keep the supportedInterfaceOrientations methods the same.

    #pragma mark- Orientation Delegate Method:
    - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
    {   Orientation = [UIApplication sharedApplication].statusBarOrientation;
        if (Orientation == UIInterfaceOrientationLandscapeLeft || Orientation == UIInterfaceOrientationLandscapeRight)
        {
    
            // self.scrollView.contentOffset = CGPointMake(self.view.bounds.size.width,1200);
    
            [scrollView setScrollEnabled:YES];
            [scrollView setContentSize:CGSizeMake(768, 2150)];
    
    
        }else if (Orientation == UIInterfaceOrientationPortrait || Orientation == UIInterfaceOrientationPortraitUpsideDown)
        {
    
            [scrollView setScrollEnabled:YES];
            [scrollView setContentSize:CGSizeMake(768, 1750)];
    
        }
    
    }
    

    In order to use navigation with orientation together, you should take a bunch of viewcontrollers like an array.

    After that checkout following methods,

    -(BOOL)shouldAutorotate
    {
        return [[self.viewControllers lastObject] shouldAutorotate];
    }
    
    -(NSUInteger)supportedInterfaceOrientations
    {
        return [[self.viewControllers lastObject] supportedInterfaceOrientations];
    }
    
    - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
    {
        return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
    }
    

    this changes in your methods will help you a lot.

    Enjoy Programming!