views:

2641

answers:

3

This is more of a general question for people to provide me guidance on, basically Im learning iPad/iPhone development and have finally come across the multi-orientation support question.

I have looked up a fair amount of doco, and my book "Beginning iPhone 3 Development" has a nice chapter on it.

But my question is this, if I was to programatically change my controls (or even use different views for each orientation) how on earth to people maintain their code base? I can just imagine so many issues with spaghetti code/thousands of "if" checks all over the place, that it would drive me nuts to make one small change to the UI arrangement.

Does anyone have experience handling this issue? What is a nice way to control it?

Thanks a lot Mark

+1  A: 

The iPhone SDK is built around having an MVC architecture, so in theory if you keep all your logic (model) separated from your UI (view) then you will only have to worry about the UI in one spot: your view controllers. For those, you could have a separate view controller for each orientation, each of which would then just be loaded with one if/else to choose which view controller to load.

The same idea holds for iPhone / iPad support, where you can load another view controller which can handle larger displays.

Winder
yeah, I had seen someone do something like this, its a good idea, thanks
Mark
+11  A: 

I do this with two simple methods in my view controller:

- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [self adjustViewsForOrientation:toInterfaceOrientation];
}

- (void) adjustViewsForOrientation:(UIInterfaceOrientation)orientation {
    if (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight) {
        titleImageView.center = CGPointMake(235.0f, 42.0f);
        subtitleImageView.center = CGPointMake(355.0f, 70.0f);
        ...
    }
    else if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) {
        titleImageView.center = CGPointMake(160.0f, 52.0f);
        subtitleImageView.center = CGPointMake(275.0f, 80.0f);
        ...
    }
}

To keep this clean you could easily compartmentalize the view adjustments/reloading/etc. with methods called from inside the single if-else conditional.

Alex Reynolds
yes, this is sort of what im doing now...thanks
Mark
the willRotateToInterface method for me is never being called. Do you have to connect something or add a listener in IB or something?
Mike Simmons
+1  A: 

It really depends on what it is you are laying out.

If you look at the Apple Settings application, you can see that they use table views for the layout, with custom cells for most rows. With that, you can allow a simple interface to rotate pretty cheaply by just filling the width of the cells. This even applies to things like Mail, where there are edit text cells in each row. And tables can easily be all transparent, with only buttons or labels visible, so they do not look like tables.

You can get a lot of milage out of the autoresizingMask of every UIView. If you have one or more items that can have a flexible height, then you can usually get an interface layout that looks good in either orientation. Depending on how it looks, sometimes you can just pin everything to the top.

In rare cases, if all the interface elements fit in a square, you can just rotate them in place.

There are two times when you must explicitly handle orientation changes. One is when a view moves from beside to below another on rotation. The other is when you have different images for each orientation, for example if you always want to be full width.

There are sometimes ways to work around both of these. You might use stretchable images or limit yourself to one view per line. Or you might lock out orientation for certain views.

If you must change the layout of views, there is an explicit layoutSubviews method. You should try to handle all you conditional layout in this one method. It is only called when the view bounds change, for example on rotation or if you have made room for the keyboard. Make a custom view for each view hierarchy that needs to respond to rotation, and layout the subviews from there.

drawnonward