The UIInterfaceOrientation property that can be put in an iPhone app’s Info.plist file, has lead me into a confusing environment of iPhone app orientation design.
At the top level, there are two ways the orientation can be considered: 1- the physical orientation of the device; 2- the orientation of the on-screen user interface.
And when developing an app, these two things can be inconsistent, and confusing.
The iPhone has 7 different physical DEVICE orientations, 3 of which I am not covering (face-up, face-down, unknown). The 4 device orientations that are considered in this writing are: landscape-left (homebutton is on right), landscape-right (home button is on left), portrait (home button is down), portrait-upside-down (home button is up).
The iPhone has 4 different interface orientations. Two are portrait and portrait-upside-down that equal the physical device portrait orientations. The other two are the landscape-right and landscape-left, but these are the opposite: interface-landscape-right = device-landscape-left, and the other is flipped too. If the device is rotated one way, the interface rotates the other way, to maintain a consistent “up” direction.
The specifics of my app:
I have a subclassed UIViewController, and its main view property is assigned a subclassed UIView object.
The main view is added to the UIApplication’s window.
Standard setup so far.
The UIView subclass has an overrided – (void) layoutSubviews method.
The UIViewController subclass has a method registered by the app delegate to receive notifications on orientation change, through the default notification centre.
There is something inconsistent between the notification centre for orientation change, and the value of [UIApplication sharedApplication].statusBarOrientation value.
Now to test:
For a start, the Info.plist file has the UIInterfaceOrientation key set to UIInterfaceOrientationLandscapeRight.
layoutSubviews will always fire first, and a check during the method for [UIApplication sharedApplication].statusBarOrientation shows landscape-right, as defined in the plist.
Then, sometimes-or-not, the orientation-change notification is sent to the registered object.
Starting the app while the device is physically in portrait, NO orientation change notification gets sent.
However, starting while the device is in any other physical orientation, then an orientation change notification is sent.
So it seems there is an expected default physical Portrait orientation, which cannot be manually defined, yet the default interface orientation can be pre-defined using [UIApplication sharedApplication].statusBarOrientation.
There are more haywire behaviours beyond this, if the device is then physically re-oriented after the app starts, more confusing behaviours.
Today was spent working on front-end app menu screens. My project originally started with the style and layout of screens drawn on paper in landscape orientation. But, before today, I did not know it’s possible to use landscape-orientation images in Interface Builder nib files. Now I know, and they can be displayed properly, if the right combination of settings are applied, such as the “Simulated User Interface Element-Orientation” setting in the inspector of IB, set to landscape, and interface orientation in the app.
Before today, I’ve done all my customized orientation positioning and rotation using the views’ center, frame, bounds and transform properties.
So, now, I can possibly adopt the built-in auto resize/rotation system. Even if I don’t use that resize/rotation system, it could also make positioning easier. It’s not difficult (now), to calculate the horizontal and vertical center of a shape, and position it within another shape whose width and height keeps changing. Still, an easier way is always a good thing!
Working with all this is leading me to the following conclusions:
- An app that has some parts that work only in landscape, and other parts that work only in portrait, should be upgraded so all parts work in all orientations.
- An app that supports either (aka every) orientation, should not have the UIDeviceOrientation key set, because it leads to confusing situations (unless someone can suggest a good reason for it).
- But, an app that supports any orientation … should, as a standard, start with the Default image designed to be portrait-oriented, not landscape, like so many iPhone games are that I’ve bought.
- This final concluding point, personally speaking, is the the biggest problem to be solved: the conflicting desires or requirements: the desire to be universal and support either/every orientation (oh the bad memories of the browser wars come flying back), and the desire also prioritize one orientation with the other less-prioritized.
That’s all, folks!
Terrible conflict, but I am happy I could articulate this whole mess!