user717452
user717452

Reputation: 111

How to rotate UIViews?

The Twitter app is a tab bar app on the iPhone. Nothing in any of the tabs will rotate, yet, when you click on a link from a tweet, the view controller that is pushed on top of it IS allowed to rotate. The only rotations I have ever doe is from tilting the device, landscape or portrait, but I don't understand how to use 2d transformations and animations to rotate views.

How do you rotate any view with that's a subclass of UIView?

Upvotes: 2

Views: 12766

Answers (7)

Hardik Vyas
Hardik Vyas

Reputation: 2253

This is the best and perfect work for me and i think this the right answer.

Just Give Number How many Times You Want To Rotate In Place Of 50 In toValue

    CABasicAnimation *rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    NSNumber *currentAngle = [CircleView.layer.presentationLayer valueForKeyPath:@"transform.rotation"];
    rotationAnimation.fromValue = currentAngle;
    rotationAnimation.toValue = @(50*M_PI);
    rotationAnimation.duration = 50.0f;             // this might be too fast
    rotationAnimation.repeatCount = HUGE_VALF;     // HUGE_VALF is defined in math.h so import it
    [CircleView.layer addAnimation:rotationAnimation forKey:@"rotationAnimationleft"];

Upvotes: 0

Benny
Benny

Reputation: 5092

Hey I had a similar problem with rotation. I had a tabbar app that I wanted to remain portrait but have a video player that allowed all rotations.

I managed to do this fairly easily by sub-classing the tabbar and only allowing portrait rotation while attaching the video player to the Root View Controller that allowed all rotations. Check out my original post here. Hope its of some help!

Upvotes: 2

Abdullah Umer
Abdullah Umer

Reputation: 4624

You can use UIView animations and Transform methods. For rotating 90 degrees:

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];

imageView.transform = CGAffineTransformMakeRotation(M_PI_2);

[UIView commitAnimations];

Upvotes: 14

Clay
Clay

Reputation: 319

@Mangesh-Vyas has some good information but doesn't quite answer the question (as I read it). The reason that the views that Twitter (among other apps) presents can rotate, when the tabbar or navbar cannot, is because they are presented modally. Views which are presented modally aren't constrained to the allowable orientations of the controller which presented them.

Edit: Perhaps you are expecting a stock UIViewController to rotate. If so then you will be disappointed, as only (to the best of my knowledge) custom subclasses can be made to rotate to arbitrary interfaceOrientations. The following code will do the trick:

 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOr‌​ientation 
{ 
    return YES;
}

Edit 2: Here's the code that makes the whole thing go:
AppDelegate.m

#import "RotateViewController.h"

@interface AppDelegate () {
    UINavigationController* nc;
}

- (void)pushVC;
- (void)openVC;

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    UIViewController* vc = [[UIViewController alloc] init];
    vc.view.backgroundColor = [UIColor blueColor];
    vc.title = @"Root";

    UIButton* b = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    b.frame = CGRectMake(50, 150, 220, 40);
    [b.titleLabel setText:@"Push VC"];
    [b addTarget:self action:@selector(pushVC) forControlEvents:UIControlEventTouchUpInside];
    [vc.view addSubview:b];

    b = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    b.frame = CGRectMake(50, 200, 220, 40);
    [b.titleLabel setText:@"Modal VC"];
    [b addTarget:self action:@selector(openVC) forControlEvents:UIControlEventTouchUpInside];
    [vc.view addSubview:b];

    nc = [[UINavigationController alloc] initWithRootViewController:vc];
    UITabBarController* tc = [[UITabBarController alloc] init];
    [tc addChildViewController:nc];

//  uncomment this line to see this work in a nav controller
//  [self.window setRootViewController:nc];
    [self.window setRootViewController:tc];

    // Override point for customization after application launch.
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
}

- (void)openVC {
    RotateViewController* rc = [[RotateViewController alloc] init];
    [nc presentModalViewController:rc animated:YES];
}

- (void)pushVC {
    RotateViewController* rc = [[RotateViewController alloc] init];
    [nc pushViewController:rc animated:YES];
}

RotateViewController is a stock subclass of UIViewController with the shouldAutorotate function from above.

Nota bene UITabBarControllers can rotate to a given interface orientation if, and only if, every one of their child view controllers returns YES for that orientation. UINavigationViewControllers can rotate to a given interface orientation if their top view controller returns YES for that interface orientation.

Upvotes: -2

Clint Warner
Clint Warner

Reputation: 1265

You are able to implement the shouldAutorotateToInterfaceOrientation method. In the Twitter app i am guessing they allow only portrait orientation for the tabBarController, but allow landscape in the modalViewController using this method. look it up in the documentation, it's pretty simple I think. I hope this answers your question!

Upvotes: -1

Mangesh
Mangesh

Reputation: 2285

Ref From How to implement UIViewController rotation in response to orientation changes?

I do this by having a root view controller (this could be a UITabBarController) and in it's viewDidLoad method i subscribe to rotation events:

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(didRotate:)
                                                  name:@"UIDeviceOrientationDidChangeNotification" 
                                                  object:nil];

Then in the didRotate: method i look at which view controller is visible when the rotation happened, and what orientation the phone is in:

- (void) didRotate:(NSNotification *)notification { 
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];

/*
DEVICE JUST ROTATED TO PORTRAIT MODE

 orientation == UIDeviceOrientationFaceUp ||
orientation == UIDeviceOrientationFaceDown

 */
if(orientation == UIDeviceOrientationPortrait) {





/*
DEVICE JUST ROTATED TO LANDSCAPE MODE
 */
}else if(orientation == UIInterfaceOrientationLandscapeLeft ||
    orientation == UIInterfaceOrientationLandscapeRight) {






}

}

Within that didRotate: you can look at which is the visible viewController and do what you want from there.

I present a modal view controller in landscape mode when a particular view controller is visible and the phone is rotated into landscape. If any other view controller is visible, i ignore the event.

I force my modal view controller to display in landscape mode in its viewWillAppear method - i can give anyone this code if they want it.

Hope this helps.

Upvotes: -1

Related Questions