I got the solution for the question asked here, but I don't like how the code is written.

This part of the code rotates the screen if it's in landscape and sets the size to match the screen. I don't like the if and the 7x else if. Can you suggest something more readable? Something like (appOrientation - fromInterfaceOrientation) == 2 than angle (M_PI / 2.0)?

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{

UIInterfaceOrientation appOrientation = [UIApplication sharedApplication].statusBarOrientation;
float width = self.view.bounds.size.width;
float height = self.view.bounds.size.height;
//NSLog(@"width %3.0f, height: %3.0f", width, height);

//    UIInterfaceOrientationPortrait           = UIDeviceOrientationPortrait,
//    UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,
//    UIInterfaceOrientationLandscapeLeft      = UIDeviceOrientationLandscapeRight,
//    UIInterfaceOrientationLandscapeRight     = UIDeviceOrientationLandscapeLeft

CGFloat angle = 0;

// rotate from Portait
if((fromInterfaceOrientation == UIInterfaceOrientationPortrait) && (appOrientation == UIInterfaceOrientationLandscapeLeft)){
angle = -(M_PI / 2.0);
}
else if((fromInterfaceOrientation == UIInterfaceOrientationPortrait) && (appOrientation == UIInterfaceOrientationLandscapeRight)){
angle = (M_PI / 2.0);
}
// rotate from PortraitUpsideDown
else if((fromInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) && (appOrientation == UIInterfaceOrientationLandscapeLeft)){
angle = (M_PI / 2.0);
}
else if((fromInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) && (appOrientation == UIInterfaceOrientationLandscapeRight)){
angle = -(M_PI / 2.0);
}

//rotate from Landscape:
else if((fromInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) && (appOrientation == UIInterfaceOrientationPortrait)){
// search for exactly the inverse...
}
// must be something more elgant code

CGAffineTransform transform = self.view.transform;
transform = CGAffineTransformRotate(transform, angle);
self.view.transform = transform;

[self.view setBounds:CGRectMake(0, 0, height, width)];


I think that you can rewrite the code in a more OO way, with the help of an NSDictionary and setting up a sort of command pattern.

You can store a sum of the two enumerator value as a key of the Dictionary in this way :

NSDictionary *dicAngles = [[NSDictionary alloc] initWithObjectsAndKeys:
(UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft), -(M_PI / 2.0),     (UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeRight), (M_PI / 2.0),
(UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft), (M_PI / 2.0),
(UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeRight), -(M_PI / 2.0),
nil];


Once you have the dictionary you can avoid the if - else control flow in this way :

 CGFloat angle = 0;
//Retrieve the angle from the dictionary
angle = [dicAngles objectForKey: ( fromInterfaceOrientation + appOrientation )];


It is only an example and not tested, but could be a more elegant solution i think ...

• How are you storing using a float as a key - an NSDictionary requires an object that implements NSCopying which I'm pretty sure a float doesn't! Sep 10, 2012 at 14:10
• You can wrap it in an Object, it's only an untested example as stated in the answer, but could give an idea of a possible way to avoid the if ...
– aleroot
Sep 10, 2012 at 14:13
• This is very error-prone solution. Not readable at all. Sep 11, 2012 at 9:00
//Angle of every orientation
double orientationAngles[] = {
orientationAngles[UIDeviceOrientationPortrait] = 0.0,
orientationAngles[UIDeviceOrientationLandscapeLeft] = (M_PI / 2.0),
orientationAngles[UIDeviceOrientationPortraitUpsideDown] = M_PI,
orientationAngles[UIDeviceOrientationLandscapeRight] = -(M_PI / 2.0)
};

//What you want is the difference between adjancent angles
double angle = orientationAngles[fromInterfaceOrientation] - orientationAngles[appOrientation];

//Putting the result into the requested interval
if (angle > M_PI / 2) {
angle -= 2 * M_PI;
}
else if (angle < - M_PI / 2) {
angle += 2 * M_PI;
}


Another possible solution, less math, more ifs.

UIDeviceOrientation orientations[] = {
UIDeviceOrientationPortrait,
UIDeviceOrientationLandscapeLeft,
UIDeviceOrientationPortraitUpsideDown,
UIDeviceOrientationLandscapeRight,
};

for (int i = 0; i < 4; i++) {
//UIDeviceOrientation previous = (i == 0) ? orientations[3] : orientations[i - 1];
UIDeviceOrientation next = (i == 3) ? orientations[0] : orientations[i + 1];
UIDeviceOrientation current = orientations[i];

if (current == appOrientation) {
if (fromInterfaceOrientation == next) {
angle = (M_PI / 2.0);
}
else { //(fromInterfaceOrientation == previous)
angle = -(M_PI / 2.0);
}

break;
}
}



As you can see, both solutions are using an array to hold the sequence of orientations. If you know the possible transitions, everything else is simple.