How to force view controller orientation in iOS 8?
For iOS 7 - 10:
Objective-C:
[[UIDevice currentDevice] setValue:@(UIInterfaceOrientationLandscapeLeft) forKey:@"orientation"];
[UINavigationController attemptRotationToDeviceOrientation];
Swift 3:
let value = UIInterfaceOrientation.landscapeLeft.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
UINavigationController.attemptRotationToDeviceOrientation()
Just call it in - viewDidAppear:
of the presented view controller.
Force View Controller Orientation in iOS 9
I was able to find a solution with the assistance of this answer: Programmatic interface orientation change not working for iOS
My base orientation logic is as follows:
// Local variable to tracking allowed orientation. I have specific landscape and
// portrait targets and did not want to remember which I was supporting
enum MyOrientations {
case Landscape
case Portrait
}
var orientation: MyOrientations = .Landscape
// MARK: - Orientation Methods
override func shouldAutorotate() -> Bool {
return true
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
if self.orientation == .Landscape {
return UIInterfaceOrientationMask.LandscapeRight
} else {
return UIInterfaceOrientationMask.Portrait
}
}
override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
if self.orientation == .Landscape {
return UIInterfaceOrientation.LandscapeRight
} else {
return UIInterfaceOrientation.Portrait
}
}
// Called on region and delegate setters
func refreshOrientation() {
if let newOrientation = self.delegate?.getOrientation() {
self.orientation = newOrientation
}
}
Then when I want to refresh the orientation, I do the following:
// Correct Orientation
let oldOrientation = self.orientation
self.refreshOrientation()
if self.orientation != oldOrientation {
dispatch_async(dispatch_get_main_queue(), {
self.orientationRefreshing = true
let vc = UIViewController()
UIViewController.attemptRotationToDeviceOrientation()
self.presentViewController(vc, animated: false, completion: nil)
UIView.animateWithDuration(0.3, animations: {
vc.dismissViewControllerAnimated(false, completion: nil)
})
})
}
This solution has the side effect of causing view[Will/Did]Appear
and view[Will/Did]Disappear
to fire all at once. I'm using the local orientationRefreshing
variable to manage what aspects of those methods are called again.
How do I force portrait orientation in a modal view controller in iOS 8?
The problem is that you are setting the supportedInterfaceOrientations
for the wrong object. You have implemented supportedInterfaceOrientations
in MyViewController. But look at your code:
MyViewController *myVC = [[MyViewController alloc] init];
UINavigationController *nav =
[[UINavigationController alloc] initWithRootViewController:myVC];
[self presentViewController:nav animated:YES completion:nil];
nav
is the presented view controller - not MyViewController. So nav
, the UINavigationController, governs whether we will rotate - not MyViewController.
So, give nav
a delegate in which you implement navigationControllerSupportedInterfaceOrientations:
- and all will be well.
How to force a UIViewController to Portrait orientation in iOS 6
If you want all of our navigation controllers to respect the top view controller you can use a category so you don't have to go through and change a bunch of class names.
@implementation UINavigationController (Rotation_IOS6)
-(BOOL)shouldAutorotate
{
return [[self.viewControllers lastObject] shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
@end
As a few of the comments point to, this is a quick fix to the problem. A better solution is subclass UINavigationController and put these methods there. A subclass also helps for supporting 6 and 7.
Lock the orientation of the app in a specific View Controller in Swift
You can force orientation with few steps:
Firstly, In your AppDelegate
define a orientation property and conform supportedInterfaceOrientationsFor
var orientationLock = UIInterfaceOrientationMask.portrait
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return self.orientationLock
}
Then declare utility struct to set orientation using KVO:
struct AppOrientationUtility {
static func lockOrientation(_ orientation: UIInterfaceOrientationMask) {
if let delegate = UIApplication.shared.delegate as? AppDelegate {
delegate.orientationLock = orientation
}
}
static func lockOrientation(_ orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation: UIInterfaceOrientation) {
self.lockOrientation(orientation)
UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation")
}
}
How to use:
//For portrait
AppOrientationUtility.lockOrientation(UIInterfaceOrientationMask.portrait, andRotateTo: UIInterfaceOrientation.portrait)
//For landscape
AppOrientationUtility.lockOrientation(UIInterfaceOrientationMask.landscapeRight, andRotateTo: UIInterfaceOrientation.landscapeRight)
Related Topics
Dateformatter'S Returns Nil For Specific Date Strings Without Time in Swift
Multiple Lines of Text in Uilabel
First and Last Day of the Current Month in Swift
Ios: Convert Utc Nsdate to Local Timezone
Why Does Viewwillappear Not Get Called When an App Comes Back from the Background
The Simplest Way to Resize an Uiimage
Load Resources from Relative Path Using Local HTML in Uiwebview
Push Notification Issue With iOS 10
How to Apply Gradient to Background View of iOS Swift App
Iphone Keyboard Covers Uitextfield
Image Resolution For New Iphone 6 and 6+, @3X Support Added
How to Add Text to an Image in iOS Swift
Appearancewhencontainedin in Swift
Swift Compiler Error: "Expression Too Complex" on a String Concatenation