iPhone OS: Rotate just the button images, not the views

I am developing an iPad application which is basically a big drawing canvas with a couple of button at the side. (Doesn't sound very original, does it? :P)

No matter how the user holds the device, the canvas should remain in place and should not be rotated. The simplest way to achieve this would be to support just one orientation.

However, I would like the images on the buttons to rotate (like in the iPhone camera app) when the device is rotated. UIPopoverControllers should also use the users current orientation (and not appear sideways).

What is the best way to achieve this?

(I figured I could rotate the canvas back into place with an affineTransform, but I don't think it is ideal.)

Thanks in advance!


Just spouting off an idea (not sure if it would work or not)...

Perhaps you could have your screen controlled by a UIViewController that supports all orientations, but have the canvas be controlled by one that only supports a single orientation (ie, returns NO in its shouldAutorotate... method).

If that doesn't work, I'd probably just go with the affineTransform route.

I discovered a way to do this, similar to what Dave DeLong proposed.

Using a transform worked, but it wasn't ideal. Although the end result (end of the animation) was what I wanted, it would stay show some kind of shaky rotation animation.

Then I found this:


Which says that a second (or third etc.) UIViewController added to the WINDOW would not receive rotation events, and therefore would never rotate. And that worked!

I created a 'fake' UIViewController with a blank view and added that as the first view controller. This receives the rotation events which I then pass on to the other view controllers that can then choose whether to rotate - the entire view or just button labels.

It is a bit hacky... But I guess the user won't notice.

Using the willRotateToInterfaceOrientation method, you should be able to use some simple logic to swap out the images:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];

    //The following if statement determines if it is an iPad, if it is then the interface orientation is allowed. This line can be taken out to support both iPhones an iPads.
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
    if (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
        //Swap images and use animations to make the swap look "smooth"
        //NSLog(@"Landscape Right");

    } else if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) {
        //Swap images and use animations to make the swap look "smooth"
        //NSLog(@"Landscape Left");

    } else {
        //Swap images and use animations to make the swap look "smooth"
} else {


To change an image in your interface programmatically:

[myUIImageView setImage:[UIImage imageNamed:@"myImage.png"]];

Also, to make sure the view doesn't auto-rotate use the shouldAutorotateToInterfaceOrientation method to tell your app to stay in portrait.

Need Your Help

ColumnSeries binding data with WPF Toolkit exception

c# wpf xaml wpftoolkit

I'm using WPF Toolkit extension to show a Column Graph that takes the data from a Dictionary<string,ulong> (where the strings are the X-values and the ulong the Y ones). This is the declarati...

Concurrent programming in OpenCL vs Grand Central Dispatch

concurrency opencl objective-c-blocks grand-central-dispatch libdispatch

With the introduction of OpenCL 2.0, OpenCL seems to have many of the features of Grand Central Dispatch (GCD), such as CLang/Apple style blocks and queues. Looking at their respective feature sets...