iPhone App Orientation Change Tutorial – change the view when the orientation changes.

In this tutorial we will change our view when the orientation on the device changes. In other words when a user changes the phone to be held in landscape mode we will load a different view then when the phone is held in portrait mode. In this example our two views are going to look completely different, but you could do the same thing while just tweaking the original view to fit better in landscape.

Portrait Screen Shot

Landscape Screen Shot

In this tutorial I am using two pictures, one a portrait and one a landscape. You can use mine or get your own.

1.) Create a new View-based Application project and name it OrientationTutorial.

2.) First thing is we will add our artwork to the project. Right-click on Resources and select Add > Existing Files … navigate to where to saved the art and click add.

Add Existing Files

Make sure you select Copy items into destination group’s folder (if needed).

Copy Items

3.) Before we do anything else we are going to set up our views. So double click OrientationTutorialViewController.xib to open it up in Interface Builder.

Our document window shows that we already have one UIView.

View selected in document window

We are going to add a second one. In the Library window find UIView.

Library

Drag it into our document window so that now we should see two UIViews.

two views now in document window

4.) Select the top View, go to Identity Inspector and name this view portrait.

Identity Inspector

This is just to help us keep the two views identified.

Then do the same thing for the other view and name it Landscape.

5.) We’re going to set up the Portrait view first, since it is pretty much all ready to go.

First let’s change the background to black.

Then let’s add a UIImageView and bring in the portrait art we added in step two.

And then let’s add a UILabel.

Here’s what mine looks like when I’m done.

Portrait View

6.) Now let’s set up the Landscape view. Double click our Landscape view in the document window to bring it into view if it isn’t already. With it still selected in the document window go to the Attributes Inspector and change the orientation to Landscape.

Attributes Inspector

At this point you can go to the Size Inspector and check our size. When I switched my view to Landscape it made the size 460 x 320. I went ahead and changed it to 480 x 320. If I had a navigation bar, or toolbar or something I would have to adjust for that. But in this tutorial I don’t need to.

7.) Make the background white if it isn’t already.

Add a UIImageView and bring in the landscape art we have.

Add a label.

Here’s what my Landscape view looks like.

Landscape View

8.) Now that we have the views set up, let’s go back to Xcode and do our coding. Open up our OrientationTutorialViewController.h file. We are going to add two IBOutlets for our two views.

Header File

9.) Now open up OrientationTutorialViewController.m.

First synthesize our outlets.

synthesize views

Then implement the shouldAutorotateToInterfaceOrientation method. It is probably commented out by default when you create the project, or a new view controller file.

We are going to set it to handle all orientations by just returning YES.

shouldAutorotateToInterfaceOrientation method

10.) Whenever a device gets rotated and the orientation changes a notification can be sent. We just need to tell our view to listen for this notification. We’ll do this in the viewDidLoad method.

viewDidLoad method

You’ll see in the second line of code there that we are calling a method named orientationChanged: so we need to set that up next.

11.) In the method orientationChanged: we are going to check to see if the orientation is portrait or not. If it is portrait we will show the portraitView, if it is not portrait we will show the landscapeView. In this tutorial we are only handling these two instances, portrait and not portrait. But we could also handle portrait upside-down, landscapeLeft or landscapeRight.

orientationChanged method

12.) Before this works we need to go back into Interface Builder and connect our outlets to the views.

Open up OrientationTutorialViewController.xib in Interface Builder. Select File’s Owner in the document window. Go to Connections Inspector and connect the outlets to the views by dragging from the little circle to the particular view in the document window.

Connection Inspector

That’s all there is to it. Click Build and Run and rotate the view by using the command key and the arrow keys.

Portrait Screen Shot

Landscape Screen Shot

Here’s the code.

This entry was posted in Uncategorized and tagged , , , , , , , , , , , . Bookmark the permalink.

29 Responses to iPhone App Orientation Change Tutorial – change the view when the orientation changes.

  1. Russ Abraham says:

    I found your site on technorati and read a few of your other posts. Keep up the good work. I just added your RSS feed to my Google News Reader. Looking forward to reading more from you down the road!

  2. Morris says:

    Exactly where is the facebook like link ?

  3. Kent says:

    I found a small bug in the code. In step 11 when we implemented the orientationChanged method I changed the if / else block to be two if blocks. By using the else it was also trying to change to landscape when the phone was laid flat, which is UIDeviceOrientationFaceUp mode.

  4. Hi Kent,

    Thanks for sharing this.

    Will your code work for my scenario?

    I am working on a financial app with a table and a graph. It’s not possible to display both of them together because of the limited space. Is it possible to change a table in vertical orientation (portrait) to a graph in horizontal orientation (landscape) on iPhone? For e.g. when the user holds the iPhone in vertical orientation he views the table. When he tilts horizontally, the table changes to a graph.

    Thanks again,
    Praveen Verma

    • Kent says:

      Absolutely that should work. You can either try and set up two views the way I have in this tutorial, or you might even try adding everything to one view and then hiding and showing what you want depending on the orientation. I haven’t done that specifically but see no reason you couldn’t.

      Try giving it a shot using this tutorial and setting up two views, one with the table and one with the graph, then switching between them when the orientation changes.

      Let me know how it goes and if you have any specific questions.

  5. Thanks Kent for your prompt reply.

  6. Craig Hind says:

    Hi Kent,

    First, thanks for this tutorial. As someone who is very new to Objective-C and iOS development, I’m finding it tough as my previous experience has been limited to VisualBasic, so not even objective code! I’ll get there…

    I am building an app that needs a different view layout depending on whether the device is in portrait or landscape orientation and there is a definite lack of information out there on how to do this. Since Apple want devs to support landscape, I would have thought they’d make how to do this clear in their own documentation.

    Initially I started off trying to use multiple XIBs to switch between views. I didn’t even realise that you could have multiple views within one XIB before I found your page, so thanks for that.

    However I have a few things that I would like your opinion on.

    I’m using Xcode 4.2, so it is a beta using the iOS 5 SDK. I created a universal app, so I have two XIBs, one for iPhone and one for iPad. I followed your instructions (with the exception of the images, I just used a single label on each view), doubling up the information supplied in both XIBs, and it does work, however I get a warning in ViewController.m on the line:

    UIInterfaceOrientation interfaceOrientation = [[object object] orientation];

    The warning is “Implicit conversion from enumeration type ‘UIDeviceOrientation’ to different enumeration type ‘UIInterfaceOrientation’” – If I change the code to reflect UIDeviceOrientation instead of UIInterfaceOrientation, the warning goes away, so I assume this is just something that has been changed between Xcode 3 and 4?

    Next, when you rotate the device starting portrait, then landscape left, then portrait upside down, the landscape right and finally back to portrait, or actually in reverse too, the animation is weird. Sometimes the view rotates in the same direction as the status bar, and sometimes the view rotates in the opposite direction to the status bar, which looks a little strange.

    And lastly, when you rotate the device, the label appears to jump from portrait to landscape without animation, whereas the view itself and the status bar do animate. Yet I have other applications that smoothly rotate between orientations. Is there something specific to your code (or perhaps mine), that would cause that difference?

    Again thanks for the tutorial!

    Regards
    Craig

  7. Ed says:

    Great post,very enjoyable read,and I agree with most of what you say,and by the way,here is a great info about iPhone Apps

  8. Mayank Mathur says:

    Hello, I am trying to make an app supporting Orientations…
    i wanted my buttons to be viewed like this in Vertical(Landscape mode) i.e
    1 2
    3 4
    5 6
    7

    and to be viewed like this in Horizontal (Portrait Mode) i.e.
    1 2 3
    4 5 6
    7

    but i am not able to do this as i am newbie in iphone Programming… can anyone please help me out.

    Thanks in Advance;

  9. Brad Larson says:

    While I respect anyone who takes the time to write tutorials for new iOS developers, there are some issues with the sample code you have here and I worry about people who are blindly copying and pasting this.

    First, why go through the effort of setting up and using a using a notification for orientation changes, when you could just as easily could be using the UIViewController delegate method -didRotateFromInterfaceOrientation:? I recommend replacing the notification and the responder method above with -didRotateFromInterfaceOrientation: or the like. Apple’s many sample applications show how to do this, and they indicate that these delegate callbacks are the proper way to handle autorotation in a UIViewController.

    Second, if you do use a notification callback, please make sure to use an NSNotification as the object type for the parameter there, rather than an id. Using a generic id can blind you to potentially passing a selector to the NSNotification that it doesn’t respond to, leading to a crash.

    Third, if you use the UIDeviceOrientationDidChangeNotification, be aware that UIDevice’s -orientation method returns a UIDeviceOrientation enum, not a UIInterfaceOrientation enum. This is causing the compiler warnings reported by others. Either compare against UIDeviceOrientation values, or use the delegate methods I recommend above, which do pass in UIInterfaceOrientation values.

    If you’re going to leave this tutorial up for others, I highly recommend fixing it so that others who copy and paste this code don’t end up with something that’s incorrect.

    • Kent says:

      Thanks for the tips. I’ve corrected the tutorial with your second and third points, but to be honest I’m having trouble with the first one. Using the didRotateFromInterfaceOrientation method produces strange results.

      I’ve tried this

      - (void)didRotateFromInterfaceOrientation: (UIInterfaceOrientation)fromInterfaceOrientation
      {
      UIDevice* device = [UIDevice currentDevice];
      UIDeviceOrientation deviceOrientation = device.orientation;

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

      and this

      - (void)didRotateFromInterfaceOrientation: (UIInterfaceOrientation)fromInterfaceOrientation
      {

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

      Both produce unexpected results. When I get some more time I’ll look into it some more and see if I can figure out a solution. In the meantime if you have a suggestion I’m all ears.

  10. raju says:

    hello,

    this post very nice,but using tableview how we can do same way .

  11. moran says:

    helpfull! thanks

  12. Gurpreet Singh says:

    Hi Kent,

    I am using same approach in my app.
    But it stop working in iOS 5.1, any pointers how to fix it.

  13. Roberto says:

    MAN, I LOVE YA! U cannot imagine how much time i was looking for this workaround..

    [iPhone 4S, iOS 5.1]

  14. CGS says:

    Gud Eveng Frnd,
    Im new for iPhone and objectivce-c Codes…
    i got Calculator app and im facing a problem regarding orientation..
    Actually my project is some Maths data along with that scientific calculator.
    I kept calc icon on front along with maths button.
    first time when i click the calc.. it works properly in both the directions but when i visit that maths button and go to cells in tabluar data and when i come back,at that time im not getting calc.. properly as it showing half calculator.
    I wasted 3days for this problem and now also im not getting a solution…
    Please take out from this problem…help me…

    Thanks in Advance.

    With Regards,
    CGS

  15. CGS says:

    Hello Frnd,
    Im new for iPhone and objectivce-c Codes…
    i got Calculator app and im facing a problem regarding orientation..
    Actually my project is some Maths data along with that scientific calculator.
    I kept calc icon on front along with maths button.
    first time when i click the calc., it works properly in both the directions but when i visit that maths button and go to cells in tabular data and when i come back,at that time im not getting calc., properly as it showing half calculator.
    Im using Xcode 4.3.1 and iphone 5.1 simulator.
    I wasted 3days for this problem and now also im not getting a solution…
    Please take me out from this problem…help me…

    Thanks in Advance.

    With Regards,
    CGS

  16. Klaws says:

    Hi Kent,

    Can you please do the same example using Xcode 4 with storyboard, cause when i did it on storyboard, the same code didnt work, it switches the orientation but the landscape view never appears.

    Thank you

  17. Myria Koushiappi says:

    Hello

    this is very helpful but I am also trying different views on orientation using storyboards and I would appreciate your help.

    thanks
    myriak

  18. Peter says:

    This stopped working with iOS 6 and Xcode 4.5.

    How to make it work now ?

    Thanks.

  19. evv rajesh says:

    hi,

    can u please tell me how to implement automatic orientations without using xib’s

    it will be very helpfull for me.

    i will be thankfull:))))

  20. Dragoraptor says:

    In IOS 6 “ShouldAutoRotateToInterfaceOrientation” method is deprecated.
    Use the newer (IOS 6 ) specific “supportedInterfaceOrientations” method.
    If you wanna support both IOS 6 and prior versions then you have to include a check to get the IOS version.

    In storyBoard situation, things are a bit different. Look up on the StackOverflow.com website, it has a huge IOS Xcode community and you will get solution/responses faster.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>