What I am Trying to Do:
Parent View that is managed by Parent View Controller SHOULD NOT ROTATE.
Child View that is managed by Child View Controller SHOULD ROTATE to all orientations.
What I Have Tried:
ParentViewController
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return .Portrait
}
override func shouldAutorotate() -> Bool {
return true
}
fun addChildViewController() {
let storyBoard = UIStoryboard(name: "Main", bundle: nil)
self.childViewController = storyBoard("Child View Controller") as? ChildViewController
self .addChildViewController(self.childViewController!)
self.childViewController! .didMoveToParentViewController(self)
self.view .addSubview(self.childViewController!.view)
self.childViewController!.view.frame = CGRectMake (40, 200, 400, 250)
}
ChildViewController
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return .All
}
override func shouldAutorotate() -> Bool {
return true
}
Supported orientations in Xcode Deployment Info are set to all four.
What I Get:
None of the View's rotate. If I set the parent's rotation to all, all views rotate together. So it's all or nothing.
UPDATE
When I try putting an observer for UIDeviceOrientationDidChangeNotification and use UIDevice.currentDevice().orientation to rotate childView using CGAffaineTransformMakeRotate , I get desired results. HOWEVER, i.e., if I rotate to landscape, and try to pull down the notification center (or if I get a system notification), which is still in the portrait orientation (because the app is natively still left in Portrait), rotated childView rotates back to portrait to honor the status bar/notification/notification center.
Stock iOS Camera App is the best example I can present. The main canvas does not rotate in to different orientations, yet the status bar, behind the scenes, rotates honoring device rotation. Also the subviews rotate within them selves to honor different orientations. I am trying to achieve this behavior....
The effect achieved in the Camera app is similar to using a combination of:
The technical note explains that the underlying implementation of autorotation involves applying a transform directly to the application's window:
Note that the Camera app does not opt out of autorotation: when using the Camera app, the orientations of Notification Center and Control Center reflect the device orientation. It is only particular views within the Camera app that appear to opt out of autorotation. In fact, this answer suggests that such apps typically utilise the
videoGravity
andvideoOrientation
properties provided by AVFoundation classes such as AVCaptureVideoPreviewLayer and AVCaptureConnection.The approach you should take depends on whether you only want to stop a parent view from rotating or whether you want to stop a container view controller such as UINavigationController from rotating (i.e. lock device orientation).
If the former, use the technique described in the technical note to fix the orientation of the parent view, and (for iOS 9) wrap rotating subviews in a UIStackView and use the
axis
property to rearrange the subviews on device rotation, or (for iOS 8) manually rotate the subviews on device rotation (as to which see this answer and this sample code).If the latter, the approach you're taking is on the right track. For sample code, see this answer. You'll need to share your code and more information about your view controller hierarchy for us to diagnose quirks involving Notification Center.
Addendum: The reason why calls to
shouldAutorotate
andsupportedInterfaceOrientations
were not being propagated to child view controllers was explained in Technical Q&A QA1688:In Swift, you can override those methods by using extensions.
From iOS developer library Technical Q&A
i.e. if you have a view named
noRotatingView
I've tried to make a demo project at https://github.com/rishi420/TestCameraRotation
After many back and forth's with Apple them selves, and them pointing to the same link Technical Q&A QA1890, I had to do this with the flowing way:
MotherViewController
MainViewController
This seem to rotate the child view's while keeping the main view static. Also the app seem to know the proper orientation when notifications come in (because mother view actually rotates behind the scenes).
Special thanks to jamesk and Warif Akhand Rishi for all the help!