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?
Thanks!
In iOS 8 transforms aren't applied to individual views owned by view controllers. Instead the rotation transforms are applied to the
UIWindow
. The result is that developers never see a rotation being applied, but rather a resize.In iOS 8 you can either override the callbacks for size class changes and perform your own transform there, or you can get the orientation events as described here: https://developer.apple.com/library/prerelease/ios/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/motion_event_basics/motion_event_basics.html.
I managed to obtain this, check:
rotation working as desired
Note: The green and the red views are subviews of the controller's view. The blue view is subview of the red view.
Idea According to https://developer.apple.com/library/archive/qa/qa1890/_index.html, we need to apply an inverse rotation to the view when it is transitioning to a new size. In addition to that, we need to adjust the constraints after rotation (landscape/portrait).
Implementation
Dimitri's answer worked perfectly for me. This is the swift version of the code in case someone needs it...
Okay after some fighting with subviews and transitionCoordinators I've finally figured it out:
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.
Swift 4 has a lot of updates, including the viewWillTransition function.