Question

I have a view that is loaded in whatever orientation the UI is. I have a requirement to allow users to select and lock the orientation they want. Below is a picture of my test app. I want to programmatically change the orientation of the view to UIInterfaceOrientationLandscapeLeft when Left is selected.

I know how to lock it. I'm just having trouble trying to rotate the view as if the device was physically rotated.

enter image description here

Here is my code:

- (void)rotateView:(UIInterfaceOrientation)toInterfaceOrientation
{
    self.interfaceOrientation = toInterfaceOrientation;
    CGFloat rotationFactor = 0;
    CGRect frame;
    switch (toInterfaceOrientation) {
        case UIInterfaceOrientationPortrait:
            frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height);
            rotationFactor = M_PI;
            break;
        case UIInterfaceOrientationLandscapeRight:
            frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.height, self.view.frame.size.width);
            rotationFactor = M_PI_2;
            break;
        case UIInterfaceOrientationLandscapeLeft:
            frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.height, self.view.frame.size.width);
            rotationFactor = 3 * M_PI_2;
            break;

        default:
            break;
    }
    // check current orientation
    if ([[UIApplication sharedApplication] statusBarOrientation] != toInterfaceOrientation) {
        self.orientationLocked = NO;
//        [[UIApplication sharedApplication] setStatusBarHidden:YES];
//        [[UIApplication sharedApplication] setStatusBarOrientation:toInterfaceOrientation];
//        [[UIApplication sharedApplication] setStatusBarHidden:NO];
        // no, the orientation is wrong, we must rotate the UI
        self.navigationController.view.userInteractionEnabled = NO;
        [UIView beginAnimations:@"rotateView" context:NULL];
        [UIView setAnimationDelegate:self];
        // setup status bar
        [[UIApplication sharedApplication] setStatusBarOrientation:toInterfaceOrientation animated:NO];
        // rotate main view, in this sample the view of navigation controller is the root view in main window
        [self.navigationController.view setTransform: CGAffineTransformMakeRotation(3 * M_PI_2)];
        // set size of view
        [self.navigationController.view setFrame:frame];
        [UIView commitAnimations];
        self.orientationLocked = YES;
    }
}

I've tried as others have suggested to no avail. I know the rotation values are not correct. I am just trying to get the view to rotate to any rotation right now.

The only issue that might be causing these suggestions to not work might be because this view is a subview of the root view. Can somebody help me programmatically rotate this view from portrait to any landscape orientation?

Was it helpful?

Solution 2

@Shan - I used your code to rotate the status bar and added a call to the following method to rotate the view. It Works!!!! So you got me half way there. Here is the rest of the code:

#define ROTATE_90 M_PI_2
#define ROTATE_180 M_PI
#define ROTATE_270 M_PI + M_PI_2

/**
 * Rotates and resizes the view
 */
- (void)rotateToSelectedOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
    CGRect viewRect = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height);
    switch (toInterfaceOrientation) {
        case UIInterfaceOrientationLandscapeLeft:
            self.view.transform = CGAffineTransformMakeRotation(ROTATE_270);
            break;

        case UIInterfaceOrientationLandscapeRight:
            self.view.transform = CGAffineTransformMakeRotation(ROTATE_90);
            break;

        case UIInterfaceOrientationPortrait:
            self.view.transform = CGAffineTransformMakeRotation(0);
            break;

        case UIInterfaceOrientationPortraitUpsideDown:
            break;

        default:
            self.view.transform = CGAffineTransformMakeRotation(0.0);
            break;
    }
    if (UIInterfaceOrientationIsLandscape(self.currentOrientation) && UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {
        viewRect = CGRectMake(0,0,self.view.frame.size.width,self.view.frame.size.height);
    } else {
        viewRect = CGRectMake(0,0,self.view.frame.size.height,self.view.frame.size.width);
    }
    self.view.frame = viewRect;
    self.currentOrientation = toInterfaceOrientation;
}

OTHER TIPS

Hmm well try below code in new project i am posting the entire code this might u needed, hope this helps u .. :)

try this in new project


#import "AnyOrientationViewController.h"

@interface AnyOrientationViewController ()
{

}

@end

@implementation AnyOrientationViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
  self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
  if (self) {
     // Custom initialization
  }
 return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Do any additional setup after loading the view from its nib.
    self.segmentControle.selectedSegmentIndex = 0;
    [self.segmentControle addTarget:self action:@selector(valueChange:) forControlEvents:UIControlEventValueChanged];
}


 - (BOOL)shouldAutorotate
 {
     return NO;
 }

 - (NSUInteger)supportedInterfaceOrientations
 {

     return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;

 }

 - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
 {

    return UIDeviceOrientationPortrait | UIDeviceOrientationLandscapeLeft | UIDeviceOrientationLandscapeRight;


 }

 - (void)valueChange:(UISegmentedControl *)sender
 {

    //hear is the code to change the orientation
    int index = sender.selectedSegmentIndex;
    switch (index) {
    case 0:
        NSLog(@"all orientation");

      //   [UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationPortrait;
         [UIApplication sharedApplication].statusBarOrientation = [[UIDevice currentDevice] orientation];
         break;
    case 1:

         if([[UIApplication sharedApplication] statusBarOrientation] != UIInterfaceOrientationPortrait)
         {
            [UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationPortrait;
         }
         break;
    case 2:

         if([[UIApplication sharedApplication] statusBarOrientation] != UIInterfaceOrientationLandscapeLeft)
         {
             [UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationLandscapeLeft;
         } 

         break;
    case 3:

         if([[UIApplication sharedApplication] statusBarOrientation] != UIInterfaceOrientationLandscapeRight)
         {
             [UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationLandscapeRight;
         }
         break;

     default:
         break;
   } 
}



 - (void)didReceiveMemoryWarning
  {
     [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
  }


If you want your app to automatically orient a given video to fill the entire screen, regardless of aspect ratio (wide or tall) and device orientation (portrait or landscape) Try this:

  1. Register for the notification generated when the orientation of the status bar changes:

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didRotateDevice) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
    
  2. Add this code to the notification object's selector method:

    - (void)didRotateDevice
    {
    CGFloat theta = 0.0;
    switch ([UIApplication sharedApplication].statusBarOrientation)
    {
        case UIDeviceOrientationPortrait:
            theta += -90.0;
            CGAffineTransform transform = self.transform;
            transform = CGAffineTransformRotate(transform, radians(theta));
            self.transform = transform;
            break;
        case UIDeviceOrientationLandscapeRight:
            if (self.transform.a != 1.0) {
                theta += 90.0;
                transform = self.transform;
                transform = CGAffineTransformRotate(transform, radians(theta));
                self.transform = transform;
            }
            break;
        case UIDeviceOrientationLandscapeLeft:
            if (self.transform.a != 1.0) {
                theta += -90.0;
                transform = self.transform;
                transform = CGAffineTransformRotate(transform, radians(theta));
                self.transform = transform;
            }
            break;
        default:
            NSLog(@"default");
            break;
    }
    
     [self setFrame:[[UIScreen mainScreen] bounds]];
    }
    

The above code will prevent just the view from rotating whenever the orientation of the device changes; all other views will rotate as expected.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top