In my program I'm moving things based on rotation, but I'm not rotating the entire view. I'm Using :
static UIDeviceOrientation previousOrientation = UIDeviceOrientationPortrait;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
[window addSubview:viewController.view];
[window makeKeyAndVisible];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(didRotate:)
name:@"UIDeviceOrientationDidChangeNotification" object:nil];
}
- (void) didRotate:(NSNotification *)notification{
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
[self doRotationStuff:orientation: previousOrientation];
previousOrientation = orientation;
}
This works as long as, when the program is launched, the device orientation is portrait, but not if the initial orientation is landscape or upside down, because [self doRotationStuff] makes changes relative to the difference from the previous orientation.
Is there a way to detect the orientation either at launch, or right before the device is rotated?
Depending on your circumstances, a simpler option may be the interfaceOrientation property of the UIViewController class. This is correct before a rotation.
Use this for the orientation of the UI if you need to determine what way are you pointing.
Not 100% sure this is right but going off the top of my head:
A more complete example on how to obtain device orientation from accelerator readings can be found here As the solution relies on accelerator readings, it wouldn't work on the simulator, so you'll have to work on the device... still looking myself for a solution that works on the simulator.
Updated:
So, from the comment discussion, it appears that you can't rely on
[UIDevice currentDevice].orientation
until the orientation actually changes for the first time. If so, you could probably hack it by getting raw accelerometer readings.Original response:
Does
[UIDevice currentDevice].orientation
return the correct orientation duringapplicationDidFinishLaunching:
? If so, you can set up your initial UI according to that orientation.If that property doesn't get set until some later time, you might try experimenting with
performSelector:afterDelay:
to initialize the UI after a small delay.This code sample is from Kendall's answer below, added here for completeness:
I'm not sure if a zero-second delay is sufficient -- this means the code for
getOriented
will run during the first pass through the event run loop. You may need to wait longer for the accelerometer readings to register onUIDevice
.Here's one way to get the orientation when the app first loads and the UIDeviceOrientation is set to UIDeviceOrientationUnknown. You can look at the transform property of the rotated view.
Mort, these answers seem somewhat of a red herring; I can't see why you can't use the following built-in method for a UIViewController class:
This method gets called automatically after a rotation has occurred (rather than with shouldAutorotateToInterfaceOrientation which only tells you it's about to happen). Handily, the variable 'fromInterfaceOrientation' contains the previous orientation. As the documentation also says, you can assume that the interfaceOrientation property of the view has already been set to the new orientation, so you then have one method with access to the old orientation and the new!
If I've missed something and you've already dismissed being able to use this method, my apologies! It just seems odd that you're creating and storing a variable for the "previous orientation" when it's provided for free in the above method.
Hope that helps!