Handling UIDeviceOrientationFaceUp & UIDeviceOrientationFaceDown
If your iPad (or iPhone) application uses UIDeviceOrientationDidChangeNotification to detect device rotation, there might be a couple cases you forget to think about. If your device is lying down flat (or upside down), there is still an implied “felt” orientation, based on how the iPad was last held before it went flat. How will iOS let you know about this? Here is what i found out when writing Dwarfland Photos:
After you sign up for UIDeviceOrientationDidChangeNotification, if your device is flat, you will receive 3 notifications. The first one will be with a value if UIDeviceOrientationFaceUp (or UIDeviceOrientationFaceDown), matching the actual current physical location of the device. Right afterwards, you get another notification, and this one will specify one of UIDeviceOrientationPortrait, UIDeviceOrientationPortraitUpsideDown, UIDeviceOrientationLandscapeLeft, or UIDeviceOrientationLandscapeRight – depending on what the UI was showing before your app started (and indicating how the user will think of the device as being rotated). This is followed right up with a third notification that brings you back to either UIDeviceOrientationFaceUp or UIDeviceOrientationFaceDown.
Essentially, the device is pretending the user really quickly shook it back to an upright position, and back down.
The best way to handle this that i found in my app was to never ever use the actual reported orientation do fo any drawing or calculation, but instead cache the last “felt” orientation, within an handler as follows:
-(void)orientationChanged:(NSNotification*)notification { UIInterfaceOrientation orientation =[[UIDevice currentDevice] orientation]; if(orientation == UIDeviceOrientationPortrait || orientation == UIDeviceOrientationPortraitUpsideDown || orientation == UIDeviceOrientationLandscapeLeft || orientation == UIDeviceOrientationLandscapeRight) { if(!currentOrientation) { currentOrientation = orientation; [self prepareScreen]; } currentOrientation = orientation; } [[UIApplication sharedApplication] setStatusBarOrientation:currentOrientation animated:YES]; } |