10

Ended up with doing this: Easiest way to support multiple orientations? How do I load a custom NIB when the application is in Landscape? Works superb!

I have made an image in Photoshop which I want to use as background for my info-screen in my iPad application. The image contains text and some icons also. Around the image I have a border which is green.

The effect I am trying to achieve is:

When the user goes from the portrait orientation to landscape orientation I want the image (just the frame and the icons) to rotate 90 degrees so the image appear in landscape mode, instead of having a portrait view of the frame in landscape. The text and icons are decoupled (different layers which I have organized in different UIImageView's)they shall rotate 90 degrees.

What I have done already is the following:

Experimented a bit with this method:

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:

and tried to do this:

self.btnFacebook.transform = CGAffineTransformMakeRotation(1.5707964);

which I think will rotate the btnFacebook property 90 degrees to the right (correct me if I am wrong) since it specifies positive radians. I can't seem to get it to work correctly though. Should'nt this rotate the button 90 degrees around its center coordinate in the frame? That wouldn't cause a change in the position of the button (the button is square)?

EDIT

Made an image:

enter image description here

As the image shows the image background (some custom graphics on it which looks good in both orientations) goes from portrait to landscape and rotates so it does not appear as portrait in landscape, the icons are decoupled from the background so they need to rotate as well because they need to be in the right orientation (it is social icons). The text however are on the same position, it only rotates 90 degrees without repositioning.

Community
  • 1
  • 1
LuckyLuke
  • 47,771
  • 85
  • 270
  • 434
  • Make sure the anchor of the views layer is at the center, what are you seeing happen instead of the desired effect? – Daniel Jun 20 '11 at 02:08
  • I don't understand why you shared an answer which refers to a solution with multiple layouts. The whole point of the question IMHO is to have just one layout and one `UIInterfaceOrientation` where some images or buttons can rotate according to the `UIDeviceOrientation`, no? In any case, that's what led me here, because I want something similar to the stock iOS camera app. The accepted answer works fine. – Maxi Mus Sep 14 '16 at 14:10

1 Answers1

21

I understand your question as that you are trying to not to rotate the interface as whole but to rotate the purple and red squares individually.

I created a UIViewController that resembles your layout.

Interface Bulder screenshot

The black square is a UIView and the white square is there only so that I can tell when the black view rotates. This view is wired to view1 property on the controller.

There are 4 buttons that are wired to btnx (x runs 1 through 4) properties.

Since I no longer want to auto rotate the interface I only support the portrait orientation.

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

To do the rotation manually, I added a method to the ViewController. It determines the angle it needs to rotate the components from portrait to current orientation, creates a rotation transform and applies it to all outlets.

- (void)deviceDidRotate:(NSNotification *)notification
{
    UIDeviceOrientation currentOrientation = [[UIDevice currentDevice] orientation];
    double rotation = 0;
    UIInterfaceOrientation statusBarOrientation;
    switch (currentOrientation) {
        case UIDeviceOrientationFaceDown:
        case UIDeviceOrientationFaceUp:
        case UIDeviceOrientationUnknown:
            return;
        case UIDeviceOrientationPortrait:
            rotation = 0;
            statusBarOrientation = UIInterfaceOrientationPortrait;
            break;
        case UIDeviceOrientationPortraitUpsideDown:   
            rotation = -M_PI;
            statusBarOrientation = UIInterfaceOrientationPortraitUpsideDown;
            break;     
        case UIDeviceOrientationLandscapeLeft:     
            rotation = M_PI_2;   
            statusBarOrientation = UIInterfaceOrientationLandscapeRight;
            break;  
        case UIDeviceOrientationLandscapeRight:    
            rotation = -M_PI_2;
            statusBarOrientation = UIInterfaceOrientationLandscapeLeft;
            break;
    }
    CGAffineTransform transform = CGAffineTransformMakeRotation(rotation);
    [UIView animateWithDuration:0.4 delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
        [self.btn1 setTransform:transform];
        [self.btn2 setTransform:transform];
        [self.btn3 setTransform:transform];
        [self.btn4 setTransform:transform];
        [self.view1 setTransform:transform];
        [[UIApplication sharedApplication] setStatusBarOrientation:statusBarOrientation];
    } completion:nil];
}

The last thing to do is to get the OS to call my method. To achieve that I added the following code to application:didFinishLaunchingWithOptions: in the AppDelegate.

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self.viewController selector:@selector(deviceDidRotate:) name:UIDeviceOrientationDidChangeNotification object:nil];

I am not sure whether this is exactly what you wanted but I believe it is at least similar so you can get some ideas from it how to solve your problem. I can provide source code for a working iPad application that I created to illustrate this.

Jiri
  • 2,206
  • 1
  • 22
  • 19
  • That could be what I need Jiri, I will try something in that direction, seems like a good answer. I let you know if I got it to work. – LuckyLuke Jun 20 '11 at 11:29
  • I have one question though, the statusbar won't rotate with this approach, right? – LuckyLuke Jun 20 '11 at 11:54
  • @Andreas the status bar won't rotate. I updated the code so it does, but it probably needs some changes to the frames of on-screen views when the status bar moves. – Jiri Jun 20 '11 at 12:13
  • Thank you! Your approach will be a future reference when I am doing something like this with rotation, however I found this: http://stackoverflow.com/questions/2496554/easiest-way-to-support-multiple-orientations-how-do-i-load-a-custom-nib-when-the/2496719#2496719 which solves the main issue, swapping image on rotation. – LuckyLuke Jun 20 '11 at 12:25
  • It's really rare that i can copy-paste an answer and it works perfectly! Thank you! – Zoltan Varadi May 27 '15 at 06:45
  • Great answer, some quick pointers: In XCode project settings, what is referred to as device orientation is of course interface orientation. The whole status bar stuff is probably not needed for most people, because if you have only one fixed interface orientation, why would you want to flip the status bar, if have it at all. And finally, the return statements in the switch clause are needed because otherwise the app would always perform a rotation back to 0°, which means returning the view (element) to the original orientation. – Maxi Mus Sep 14 '16 at 14:14