What's the correct way of designing multi-orientation iPad app nowadays? I've read a lot of Apple docs, web resources and some SO Q&A. Here are my initial requirements:
header.png
and header-landscape.png
UIImageView for example.So what do I do?
willRotate
handler? What are proper approaches to this issue as of today?
I actually think this is a really complex subject, like most architectural issues. I don't believe you should try to solve the problem with only one technique.
For the sake of not crowding off all the other answers on this page, I posted a full-writeup on my blog and a link to some sample code, too
It should be preferred to express your UI in .xib files, although the extent to which you allow yourself to diverge from this partly depends on the skill set of the people who will modify your app in the future. It may not just be programmers!
It should be strongly preferred to implement one logical view with one .xib file, and one UIViewController
subclass. Try really hard to do that. Setting autoresizesSubviews=YES
on your XIB's root view
, and properly adjusting the child views' autoresizingMask
to flex with changes in screen size/orientation can go a long way.
But, that won't always be enough. If your layout needs adjusting in landscape orientation, beyond what autoresizing can handle, I use two main options. Which one you should choose depends on your view's content.
If the layout for portrait vs. landscape is not too different, then I recommend staying with one .xib, and having a little bit of code in your View Controller to adjust layout on rotation.
If the landscape vs. portrait differences are really significant, then I recommend having one .xib for each orientation (with a strict naming convention, like MyViewController.xib
and MyViewController-landscape.xib
). But, both .xib files should connect File's Owner to the same View Controller class! To me, this is key.
If you are ever going to do anything but the preferred alternative, I recommend creating a reusable UIViewController
base class to automate this, and keep it consistent. It's more work than you might think at first, and it's silly to keep doing it in every UIViewController
subclass that needs rotation handling.
I created such a base class, and put it in a sample project here. You can see a Hello World example of how I think all three scenarios should be handled:
FirstViewController
)SecondViewController
)ThirdViewController
)The RotatingViewController base class I use is equally applicable to iPhone apps. I actually have a more complicated version that handles maintaining iPad and iPhone, portrait and landscape layouts (for Universal apps).
But, this question was only about iPad, so I stripped it down, to be easier to understand.
My base class also has a utility imageNamed:
method that helps load images that are proper for the current orientation (named with a image-landscape.png convention). However, I think stretchable UIImages should be used instead the vast majority of the time.
I didn't do this, but the RotatingViewController
could also try to walk its subviews
tree and update the image
property on UIButton
or UIImageView
objects, when device orientation changes. I didn't go to that length, but you could.
More rationale for these recommendations is available on the blog post I reference
So, with the lack of answers to this question and time is an issue, I ended up doing the following:
willAutoRotate
handler. This method gave me flexibility of creating at list majority of UI in IB. I still need to keep code to re-arrange elements to different orientations but usually this only involves setFrame
methods for labels, buttons etc, and imageNamed
for images. Which is much smaller scope then creating all UI in code directly.
I will open a bounty on this question as soon as SO allows, because I think this question is very important and useful for any developer creating universal and multi-orientation app for iPad/iPhone.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With