Dimitri Dimitri - 11 months ago 77
iOS Question

Disable autorotate on a single subview in iOS8

I'm writing a drawing app and I don't want the drawing view to rotate. At the same time, I want other controls to rotate nicely depending on the orientation of the device. In iOS 7 I've solved this via:

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
float rotation;

if (toInterfaceOrientation==UIInterfaceOrientationPortrait) {
rotation = 0;
else if (toInterfaceOrientation==UIInterfaceOrientationLandscapeLeft) {
rotation = M_PI/2;
} else if (toInterfaceOrientation==UIInterfaceOrientationLandscapeRight) {
rotation = -M_PI/2;

self.drawingView.transform = CGAffineTransformMakeRotation(rotation);
self.drawingView.frame = self.view.frame;

But on iOS 8 even though the function is called and the transform is set correctly, it does not prevent the view from rotating.

I've tried creating a view controller which simply prevents the rotation of it's view and add it's view to the view hierarchy, but then it doesn't respond to user input.

Any ideas?


Answer Source

Okay after some fighting with subviews and transitionCoordinators I've finally figured it out:

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
    CGAffineTransform targetRotation = [coordinator targetTransform];
    CGAffineTransform inverseRotation = CGAffineTransformInvert(targetRotation);

    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {

        self.drawingView.transform = CGAffineTransformConcat(self.drawingView.transform, inverseRotation);

        self.drawingView.frame = self.view.bounds;
    } completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {

What I do is, I calculate the inverse of the transform applied to the view and then use it to change the transform. furthermore I change the frame with the view bounds. This is due to it being full screen.