Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
422 views
in Technique[技术] by (71.8m points)

iphone - How to properly design multi-orientation iPad application

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:

  • This has to work on iOS 5 and above. No need to create back compatibility with previos versions of iOS.
  • I would like if possible to have portrait and landscape UI defined in different NIB files.
  • My NIB files will have different images for same UI elements in different orientation (like I will have header.png and header-landscape.png UIImageView for example.
  • App will have several screens and I need to be able to switch orientation on each of them.

So what do I do?

  • Create one VC per screen and replace underlying view in willRotate handler?
  • Create one VC per orientation? But then how do you switch them properly?
  • Simply re-arranging elements won't work (I think) because I would have to reload images.
  • Write everything in code (I would really hate this idea)?

What are proper approaches to this issue as of today?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

Summary

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!

Preferred Option

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.

Option One

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.

Option Two

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.


Solution

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:

  • One view controller and one .xib, with autoresizing only (my FirstViewController)
  • One view controller and two .xibs, with switching between them automated (my SecondViewController)
  • One view controller and one .xib, with minor programmatic layout on rotations (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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...