Search code examples
iosios6uiimageviewautorotate

Setting up AutoRotation and preferred orientation based on a photos orientation


I have a VC where the user either takes a photo or selects one from their library.

Once the photo is taken/selected it is passed to a UIImageView on the next VC.

I would like to show this View Controller, ONLY in the Orientation that the image is in. So if the user takes a photo in landscape left (once they select Use), the next view controller should load in Landscape left with that image in the UIImageView. If they take the image in portrait the view controller loads in portrait. Once the VC is loaded in the correct orientation, it should not move (rotate any more).

This is what I have tried so far, but cannot get it to work how I expect:

#pragma mark -
#pragma mark - Auto Rotation Overrides
- (BOOL)shouldAutorotate {
    if (self.photoImage != NULL) {
        // Check that photoImage has an image
        if (self.photoImage.imageOrientation == 1 || self.photoImage.imageOrientation == 0) {
            // Landscape left = 0, Landscape rigt = 1
            return YES;
        } else {
            // Portrait normal = 3, portait upside down = 2
            return NO;
        }
    }

    // Fallback to portrait
    return NO;
}

-(NSUInteger)supportedInterfaceOrientations {
    if (self.photoImage != NULL) {
        // Check that photoImage has an image
        if (self.photoImage.imageOrientation == 0) {
            return UIInterfaceOrientationMaskLandscapeLeft;
        } else if (self.photoImage.imageOrientation == 1) {
            return UIInterfaceOrientationMaskLandscapeRight;
        } else {
            return UIInterfaceOrientationMaskPortrait;
        }
    }

    // Fallback to Portrait
    return UIInterfaceOrientationMaskPortrait;
}


- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    if (self.photoImage != NULL) {
        // Check that photoImage has an image
        if (self.photoImage.imageOrientation == 0) {
            return UIInterfaceOrientationLandscapeLeft;
        } else if (self.photoImage.imageOrientation == 1) {
            return UIInterfaceOrientationLandscapeRight;
        } else {
            return UIInterfaceOrientationPortrait;
        }
    }

    // Fallback to Portrait
    return UIInterfaceOrientationPortrait;
}

-----EDIT-----

As shouldAutoRotate is not called until the device is actually rotated, how do I get it to automatically on viewDidLoad change the orientation based on the image orientation. I see the supportInterfaceOrientations method is called and only a Landscape is returned, but doesn't move the view straight away...?

-----EDIT2-----

Does preferredInterfaceOrientationForPresentation work in IOS6 too? I can setup my Navigation Controller subclass to look at self.topViewControllers preferredInterfaceOrientationForPresentation, however this seems to mean that every single topViewController needs to have this method. Ideally I want to setup the subclass to say: if the topViewController has a response to preferredInterfaceOrientationForPresentation, then use that else portrait/default. Can this be done?

If so, surely I can update the preferredInterfaceOrientationForPresentation which would load that VC in the correct orientation then shouldAutoRotate would control it not being rotated back to another orientation?


Solution

  • From what I understand, there is no way to force a rotation event, so you have to come with some tricksy stuff. I did a google search for "force a uiview to rotate" and found some links that may help:

    Removing and re-adding the view from the window

    Rotating the view with a transform

    Personally, I would try the transform first, here is the relevant code:

    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:YES];
    self.view.transform = CGAffineTransformIdentity;
    self.view.transform = CGAffineTransformMakeRotation(degreesToRadian(90));
    self.view.bounds = CGRectMake(0.0, 0.0, 460.0, 320.0);
    

    I am not sure if setting the status bar orientation will change the orientation of the nav bar, if you are using one...