A couple of days ago I wrote a quick tutorial on how to support multiple orientations in an iPhone app without any stress. Then the more astute of you will have noticed it disappeared. Well, I decided to make my Layout Manager a little more friendly and easy to use. Down at the bottom of this post you’ll find a project with a couple of demo views and the manager itself. It’s very easy to follow. Here’s the back story…
Until recently I’ve only bothered supporting portrait orientation in my iPhone apps. I suspect this was largely driven by a lack of need to support anything else, and partially an inherent laziness which always seems to prevail over my work. Anyway, turns out that sometimes I DO need to support different orientations so I went to work looking for a clean way to do it and arrived at the following solutions….
- Create two view controllers and swap them out with a navigation controller.
- Programmatically move stuff when the orientation changes.
- Run around panicking about the fact you can’t support orientation changes.
In all my searching, I didn’t find an easy way to do it, so I went for option 2 and set about making a nice clean way to get it all to just ‘happen’ without too much effort. Eventually I arrived at the solution that this blog post is all about. Here’s what I did…
Created my test ViewController as usual, with a portrait XIB. I laid out my items on this view as I wanted them. I then (very importantly) gave each item I wanted to move a unique TAG number. Then I created a second view which I made landscape. I copied and pasted all the items from the portrait view (complete with TAG numbers still in tact) and arranged them until I was happy.
Now here’s the cunning part. I wrote a new class called LayoutManager. Within this class, I created the ability to store a dictionary of all the frames for each item in my form for both landscape and portrait, using the tag number as the key for the dictionary. Then when I call my view, in the init method I create an instance of this class and pass it (a) the current view controller view and (b) the name of the NIB file for the landscape view.
The class then goes and opens the landscape NIB file, and for each TAG which is greater than zero (which matches a tag in the portrait view) I store both the landscape and portrait frames.
Now that I have all the transitional positions for my items, I simply get the class to reposition all the tagged items based on the current orientation. I added a simple animation to the movement to tidy it up a little (and the ability to switch off animation for when orientation has changed between views.
The result was a clean implementation of two views which I can still change the design of, but without having to change any code!
Don’t believe me…. take a look and have a play with it. I’m sure there are better ways to accomplish this but this method certainly works without too much of an issue. You’re free to use this class as you will but please post a message on this blog item if you do!
That’s all folks!