Tag Archives: orientation

Custom rotation/orientation, and almost too much code

I have my major iPhone project game-app organized in this manner:

Custom class for appplication delegate class (as all apps have)

it has a generic UIWindow as the view property.

To this window, I add a background wood image.

Then the app delegate creates an instance from a nib, of my main game object view-controller-subclass.  I actually use this view controller subclass as the main model of the game, instead of separating it out to form a more appropriate model-view-controller relationship model.

The game object has a custom UIView subclass, NOT the one for the OpenGL view.

This view is permanently in UIInterfaceOrientationLandscapeRight (the default orientation set in the Info.plist).
Extra trivia: when an orientation change occurs, I manually rotate subviews of the main game view individually.  This is done by  picking one of my five global CGAffineTransform variables created with assigned values

CGAffineTransform transRot0 = CGAffineTransformMakeRotation( 0 );
CGAffineTransform transRotMinus90 = CGAffineTransformMakeRotation( – M_PI / 2 );
CGAffineTransform transRot90 = CGAffineTransformMakeRotation( M_PI / 2 );
CGAffineTransform transRotMinus180 = CGAffineTransformMakeRotation( – M_PI );
CGAffineTransform transRot180 = CGAffineTransformMakeRotation( M_PI );

The two 180s are very important, only if using animations to transition with style.  And that’s what I am doing (in some cases).
The UIInterfaceOrientationLandscapeRight is the same thing as UIDeviceOrientationLandscapeLeft (when you rotate the iPhone or iPod touch from having the home-button down = portrait, to having it on the right-side = device landscape left, the interface must rotate the opposite direction = landscape right, to maintain the same upward direction so you don’t have to tilt your head).  The direction of positive rotation is clockwise,  so if someone starts the app and has the home button down = device/interface portrait, the interface must rotate counter-clockwise 90 degrees, thus I assign transRotMinus90.
NOW IF the device is rotated again to device-landscape-right/interface-landscape-left, all my subviews including the play-screen and main menu will need to be rotated to a 180 degree transform rotation. But because the view was previously a Minus-90 degree, the next rotation should be a Minus-180 degree.  If using animations and assigning all subviews a 180 degree rotation from minus-90 degrees, rotating from portrait to device-landscape-right will have a terrible looking 270 degree opposite rotation.  Again, it isn’t important to do minus-180 if there is no animation.

That’s a long-winded orientation discussion.

And as mentioned, the game-viewcontroller has a custom subclass UIView.  It has two primary views added as subviews (there are other subviews which are not important for discussion).  The first primary view is a view from a custom subclass of UIViewController controlling the main menu, and the second of the two primary views is a custom subclass of UIView which is for the OpenGL graphics.

And I haven’t been working on this today, but I mentioned all of my game’s orientation methods are contained within the main game class, not the custom subview class.

All of this orientation code, and much more (multiple levels of initializing and setup, haha) combine to a pretty large line count – today I went over 6000 lines in this one file.

Everything is very well organized still, so I have no problem navigating or finding things.  Woohoo.  Otherwise, it would be a colossal nightmare.

Posted in Technology | Tagged , , , , , , , , | Leave a comment

iPhone app orientation (portrait vs landscape)

Introduction

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.

Setup

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.

Testing

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.

Conclusions

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!
Posted in Technology, Thoughts | Tagged , , , , , , | Leave a comment

iPhone accelerometer orientation

After searching for information about the iPhone accelerometer in search engines and the apple documentation, I did not find anything simple as what I am going to post here.

This is a bit of a tutorial, or just an explanation, how to determine the iPhone and iPod Touch (possibly the iPad) and its orientation relative to the flat ground at our feet.

The orientation uses 3-dimensional coordinate concepts, so a person has to be familiar with x, y, z and rotation concepts.  To get the information, you should be developing a native app (I don’t know if this works in Mobile Safari for web apps yet).  The UIAccelerometer class has a class method to provide you the shared accelerometer. The way to do this follows:

[[UIAccelerometer sharedAccelerometer] setDelegate: myObject ];

Additionally, setting the time interval (measured in seconds) to receive updates is a good task:

[[UIAccelerometer sharedAccelerometer] setUpdateInterval:( 1.0f / 30.0f )];

Now your class that myObject is instantiated from must implement the following method (the actual variable names can be customized to whatever you want):

– (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration

The UIAcceleration object called “acceleration” contains the important 3-dimensional values.

* * *

The iPhone cannot determine how far off the ground it is, but it can tell which side/edge/face of itself is closest to the ground.  That’s the point I am going to work with. Pretend the iphone is a 6-sided box, even though the 4 side edges are very slim, they are still sides of the box.

The device has 6 orientations, when one of the sides is directly facing the ground:

  1. Portrait
  2. Portrait upside-down
  3. Landscape left (rotate the device counter-clockwise 90 degrees from portrait)
  4. Landscape right (rotate the deviceclockwise 90 degrees from portrait)
  5. Face up
  6. Face down

Each time the accelerometer:didAccelerate method responds, you can get information about its orientation from the UIAcceleration object (using the above name) as follows:

float x = acceleration.x;
float y = acceleration.y;
float z = acceleration.z;

And now, comes the final bit of useful information, the pictures.

Basically, the pictures show the values of x, y, z,  for the 6 different orientations.

The way I personally interpret this is by way of the relative positions of one side to its opposite side.  The screen and the back are Z sides, the top with the lock button and bottom with the dock connection are the Y sides, and the two left-right edges are the X sides.

iPhone face-down

iPhone face-down, z approaches 1

iPhone face-up

iPhone face-up, z approaches -1

iPhone portrait

iPhone portrait, y approaches -1

iPhone portrait upside-down

iPhone portrait upside-down, y approaches 1

iPhone landscape right

iPhone landscape right, x approaches 1

iPhone landscape left

iPhone landscape left, x approaches -1

Until I wrote all this info down on paper, exactly as it’s described here, I couldn’t figure out how to interpret weird angles.

I had to do this research because the pre-packaged method for detecting orientation-changes was causing my app to jump back and forth.  Probably has to do with the update frequency too.  But this way now, I can build my own custom orientation code.

Take care everyone.

Posted in Technology | Tagged , , , , , , , , , | 2 Comments