Reputation: 1118
I'm writing an iOS application with some fixed (portrait) views and some orientation dependent views (portrait, lanscape left and landscape right).
The views are contained in a Custom Navigation Controller based on the following code:
class CustomNavigationViewController: UINavigationController {
override func supportedInterfaceOrientations() -> Int {
return self.topViewController.supportedInterfaceOrientations()
}
override func shouldAutorotate() -> Bool {
return self.topViewController.shouldAutorotate()
}
}
I'm implementing supportedInterfaceOrientations()
and shouldAutorotate()
inside nav child controllers.
Here is a Test Controller
class TestViewController: UIViewController {
var shouldRotate: Bool = false
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
self.shouldRotate = true
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
convenience init(rotation shouldRotate: Bool) {
self.init(nibName: "TestViewController", bundle: nil)
self.shouldRotate = shouldRotate
}
override func supportedInterfaceOrientations() -> Int {
if shouldRotate == false {
return UIInterfaceOrientation.Portrait.rawValue
} else {
return super.supportedInterfaceOrientations()
}
}
override func shouldAutorotate() -> Bool {
return shouldRotate
}
override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) {
println("from: \(fromInterfaceOrientation.rawValue)")
}
@IBAction func buttonTapped(sender: AnyObject) {
let newvc = TestViewController(rotation: true)
self.navigationController?.pushViewController(newvc, animated: true)
}
}
The first controller is instantiated inside the AppDelegate
with rotation: false
. The other controllers are created with rotation: true
and pushed after tapping the button.
Here is a screenshot of the view:
If I change orientation on the controllers after the first one (the rotable ones) I get the following result:
The controller xib uses autolayout and if I rotate the device before tapping the button it works as expected with the view filling the whole screen.
Also, if I tap the back button while the phone is in landscape the first view is locked in this state:
I'm deploying the app to iOS 8.
How can I make the first view portrait only and the other views correctly layed out after a rotation?
Upvotes: 5
Views: 3062
Reputation: 9354
Problem is because shouldAutorotate
return false
.
Your FixedViewController should return shouldAutorotate
value true
, but supportedInterfaceOrientations
should be for example only portrait.
Why do you need it?
When you come back (by using popViewController
or dismissViewController
) to your FixedViewController (which supports only portrait mode) from another RotateViewController in landscape mode, it should autorotate, to come back to portrait mode
Upvotes: 0
Reputation: 2307
It's probably doesn't matter since it's only printing out a debug message, but don't forget that didRotateFromInterfaceOrientation(_:)
was depreciated in iOS 8 with viewWillTransitionToSize(_:withTransitionCoordinator:)
taking it's place for responsibilities of a change in view size (which includes rotation).
I think you're on the right track, but instead of overriding both shouldAutorotate()
and supportedInterfaceOrientations()
only override supportedInterfaceOrientations()
.
I just did a quick POC to see if it would work. I'm not setting a flag when creating the view controller (and using Swift 2) but you get the idea:
class RotatingViewController: UIViewController {
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.All
}
}
class FixedViewController: UIViewController {
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.Portrait
}
}
class NavigationController: UINavigationController {
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return self.topViewController?.supportedInterfaceOrientations() ?? UIInterfaceOrientationMask.All
}
}
I think what's happening in your demo is that when you're transitioning to a view controller that is fixed, you're asking it to go into a portrait orientation (which it is) but then not allowing the screen to rotate back to portrait mode.
So.. just try deleting your 'shouldAutorotate()' in your CustomNavigationViewController
and see if that works.
Upvotes: 2