How to rotate sub-views around their own centres?
Asked Answered
B

2

37

Is it possible to rotate a view around its own centre?

In my present implementation the sub-views (buttons, etc) seem to move along a funny path before they end up in the desired positions (since the super view's coordinate system is rotated). I would like the views to spin 90 degrees around theire own centres as in the picture below.

desired rotation

Bal answered 8/1, 2012 at 11:43 Comment(3)
+1 for nicely illustrated questionStanley
Do you want the status bar to remain still, or is that just a overlooked in the illustration?Cantus
@Cantus While it is not my primary objective, it would be okay if it remain still! In my present implementation, the subviews move along a "funny path" because the super view (or root window?) is rotating.Bal
C
16

I really like this question. I also find the rotation animation jarring for some interfaces. Here's how I would implement what you have pictured. A simple @interface will be just fine. Note: I am using ARC.

#import <UIKit/UIKit.h>
@interface ControllerWithRotatingButtons : UIViewController
@property (strong, nonatomic) IBOutlet UIButton *buttonA;
@property (strong, nonatomic) IBOutlet UIButton *buttonB;
@property (strong, nonatomic) IBOutlet UIButton *buttonC;
@end

The appropriate outlet connections are made to the buttons in the .xib:

enter image description here

ControllerWithRotatingButtons.m:

#import "ControllerWithRotatingButtons.h"
@implementation ControllerWithRotatingButtons
@synthesize buttonA = _buttonA;
@synthesize buttonB = _buttonB;
@synthesize buttonC = _buttonC;
-(void)deviceRotated:(NSNotification *)note{
    UIDeviceOrientation orientation = [UIDevice currentDevice].orientation;
    CGFloat rotationAngle = 0;
    if (orientation == UIDeviceOrientationPortraitUpsideDown) rotationAngle = M_PI;
    else if (orientation == UIDeviceOrientationLandscapeLeft) rotationAngle = M_PI_2;
    else if (orientation == UIDeviceOrientationLandscapeRight) rotationAngle = -M_PI_2;
    [UIView animateWithDuration:0.5 animations:^{
        _buttonA.transform = CGAffineTransformMakeRotation(rotationAngle);
        _buttonB.transform = CGAffineTransformMakeRotation(rotationAngle);
        _buttonC.transform = CGAffineTransformMakeRotation(rotationAngle);
    } completion:nil];
}
-(void)viewDidLoad{
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceRotated:) name:UIDeviceOrientationDidChangeNotification object:nil];
}
-(void)viewDidUnload{
    [super viewDidUnload];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
@end

And that's it. Now when you rotate your device the screen will not rotate but the buttons will as shown:

enter image description here

Of course if you only want the button's labels to turn you would simply apply the transform to the _buttonA.titleLabel instead.

Note: Please note that once the device is rotated as far as any touches not on the buttons are concerned the device is still in portrait, but your response to my comment seems to indicate that's not a problem for you.

Feel free to leave a comment if you have a related question.

Cantus answered 10/1, 2012 at 6:29 Comment(1)
Thanks a lot! The code is elegant and the subviews now move so slick!Bal
L
4

You can manualy rotate any UIView subclass using transform property.

#import <QuartzCore/QuartzCore.h>

myView.transform = CGAffineTransformMakeRotation(M_PI/2);
Loni answered 8/1, 2012 at 11:51 Comment(2)
It looks easy! But somehow I must prevent the main view from rotating, and find out where to place your code snippet.Bal
You should look into the UIViewController rotation callbacks, such as – shouldAutorotateToInterfaceOrientation: and – willRotateToInterfaceOrientation:duration:. See if you can keep the view from rotation, but still subscribe to the rotation events and change your subviews accordingly.Potomac

© 2022 - 2024 — McMap. All rights reserved.