views:

364

answers:

2

With no developer interaction you can have a view resize itself to support an orientation, in many cases this is fine, but what if you need to change the layout of your UI objects to better suit the new orientation?

Apples answer is to:

  • Have two separate ViewControllers with xibs that reflect the desired layout.
  • Designate a master ViewController, (recommended portrait).
  • Subscribe to beginGeneratingDeviceOrientationNotifications
  • In the notification event method (master), check the orientation and either push or pop the slave ViewController as a modal.

At face value, if the layout contains a number of UITextFields, changing the orientation clears the fields (from the users point of view) suggesting that a field copy method is also needed in the notification event method. Unless there is an automated provision for this? (or an alternative pattern)

But what if you want to have some nice short-delayed UI frame translation animations?

Alternatively, rather than having two View controllers I have used CGAffineTransforms to animate UI object frame changes (triggered on willRotateToInterfaceOrientation) with the added bonus of looking sexy, but the code doesn't look very elegant.

Im unaware of any other solutions.

To get to the point: What is the most efficient and fastest, way to change UI object layouts on orientation events that preferably facilitates frame translation animation?

Luke

+1  A: 

The transforms are the easiest to integrate with transition animations.

I usually solve this problem by using a different view/view-controller pair for each orientation. The trick to making this work seamlessly is to have the data already entered constantly updated in the external data model object. Each view controller then automatically populates its view's UI from the data model. That way you don't have to worry about moving data between view controllers which can get messy if you have a lot of views.

TechZen
You said that the transforms are the 'easiest' way to integrate with transition animations, does that mean there is a way for a view to animate object translations by comparing the objects frames of another view? bearing in mind that if it was complex, there would be little point
Luke Mcneice
No, but you can put the transform in an animation block such that it looks like the UI elements are sliding into their new positions. In that case, you would use the same view for different orientations but just animate rearranging everything. However, like I said, I prefer to use multiple views. It all rather depends on what kind of visual effect you're shooting for.
TechZen
+2  A: 

The most efficient way is to do the layout in code. The downsides are that you have to write ugly code and avoid IB. The upshots are elasticity and performance. I wrote a method in my view controller which accepts UIInterfaceOrientation as an argument and lays out its views accordingly. Then I call this method from -willAnimateRotationToInterfaceOrientation:duration:. Sure, the code is very ugly, but fast. Basically, I just set a bunch of frame properties there.

Costique
Do you usually statically assign frame coordinates or do you check the orientation and subtract/add a relevant translation value?
Luke Mcneice
It depends on whether a control's position is static/absolute or relative to other controls. Usually there are always some varying-length labels, which have to be taken into account when positioning icons, badges, etc. Right- and bottom-aligned elements always include the superview's bounds size in their frame calculation. You can obviously apply transforms to _some_ views, but I think calculating each view's frame "from scratch" is more straight-forward and less error-prone. Especially given that you just don't know what screen size the next iOS device is going to have.
Costique