Search code examples
uiviewcontrollerrotationuiviewanimationcgaffinetransform

UIView rotate orientation AFTER it's displayed


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?


Solution

  • @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;
    }