问题
Can I set a portrait orientation and lock orientation just in one controller?
I did try:
override func supportedInterfaceOrientations() -> Int {
return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}
override func shouldAutorotate() -> Bool{
return false
}
but it doesn't help me. Must I to add anything else?
回答1:
This code should work:
override func supportedInterfaceOrientations() -> Int {
return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}
override func shouldAutorotate() -> Bool{
return false
}
override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
return UIInterfaceOrientation.Portrait
}
If it is now working for you, then I suppose your controller is in some another controller(UINavigationController
, UITabBarController
, UISplitViewController
). In this case you need to use this code in that parent controller.
If your navigation controller contain more than one view controller, and you need to disable orientation only for some of them, then you need to inherit UINavigationController
class and write there something like:
class NavigationController: UINavigationController {
var shouldRotate: Bool = true
override func supportedInterfaceOrientations() -> Int {
return shouldRotate ? Int(UIInterfaceOrientationMask.Portrait.rawValue) : Int(UIInterfaceOrientationMask.All.rawValue)
}
override func shouldAutorotate() -> Bool{
return shouldRotate
}
}
Then in controller that you need to disable orientation you can disable it for your navigation controller:
class ViewController: UIViewController {
var lastControllerRotationStatus: Bool?
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
if let navigationController = self.navigationController as? NavigationController {
lastControllerRotationStatus = navigationController.shouldRotate
navigationController.shouldRotate = false
}
}
override func viewDidDisappear(animated: Bool) {
super.viewDidDisappear(animated)
if let navigationController = self.navigationController as? NavigationController {
navigationController.shouldRotate = lastControllerRotationStatus ?? true
}
}
}
But remember, that you need to restore old rotation status after your controller will be pushed out navigation controller. In this example I'm saving rotation status before changing it, and restoring it after controller disappeared. Also you can use some other approach. For example you can overload UINavigationController
method popViewController
, and there set shouldRotate
to false.
The same approach with variable setting from controller you can use for controlling rotation from AppDelegate
method application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow) -> Int
Then you do not need to inherit from navigation controller.
Your AppDelegate
class code will look like:
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var shouldRotate = true
func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> Int {
return shouldRotate ? Int(UIInterfaceOrientationMask.All.rawValue) : Int(UIInterfaceOrientationMask.Portrait.rawValue)
}
}
And your controller code will look like:
class ViewController: UIViewController {
var lastControllerRotationStatus: Bool?
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
if let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate {
lastControllerRotationStatus = appDelegate.shouldRotate
appDelegate.shouldRotate = false
}
}
override func viewDidDisappear(animated: Bool) {
super.viewDidDisappear(animated)
if let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate {
appDelegate.shouldRotate = lastControllerRotationStatus ?? true
}
}
}
回答2:
If you want Portrait orientation but you want to lock only one viewController (for example in landscape) you can do it in this way:
This worked for me with Swift 2.0
AppDelegate
var shouldRotate = true
//MARK: - Func to rotate only one view controller
func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
if (shouldRotate == true){
return UIInterfaceOrientationMask.All
}
return UIInterfaceOrientationMask.Landscape
}
ViewController
override func viewDidLoad() {
super.viewDidLoad()
// 1. lock the rotation
let appdelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appdelegate.shouldRotate = false
// 2. Force the device in landscape mode when the view controller gets loaded
UIDevice.currentDevice().setValue(UIInterfaceOrientation.LandscapeRight.rawValue, forKey: "orientation")
}
override func shouldAutorotate() -> Bool {
// 3. Lock autorotate
return false
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return [UIInterfaceOrientationMask.LandscapeRight, UIInterfaceOrientationMask.LandscapeLeft]
}
override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
// 4. Only allow Landscape
return UIInterfaceOrientation.LandscapeRight
}
// 5. Restoring the locked-rotation before controller disappeared
override func viewWillDisappear(animated: Bool) {
let appdelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appdelegate.shouldRotate = true
}
回答3:
I found this on a similar question. Link
"First of all, I really thank you to zellb who give me this answer and make me understand.In order to set device orientation for one view controller to portrait and others to both,you can set this at AppDelegate.swift with this function that had supportedInterfaceOrientationsForWindow
func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow) -> Int {
return checkOrientation(self.window?.rootViewController?)// This is the custom function that u need to set your custom view to each orientation which u want to lock
}
And here is the function which check for each view controller to set Portrait or All Orientation base on what u want.
func checkOrientation(viewController:UIViewController?)-> Int{
if(viewController == nil){
return Int(UIInterfaceOrientationMask.All.rawValue)//All means all orientation
}else if (viewController is SignInViewController){
return Int(UIInterfaceOrientationMask.Portrait.rawValue)//This is sign in view controller that i only want to set this to portrait mode only
}else{
return checkOrientation(viewController!.presentedViewController?)
}
}
and dont forget to set the view controller which u want to lock at Attribute Inspector which include orientation to "Portrait" and others to "Inferred""
Hope that helps.
回答4:
**Add to your AppDelegate file:*
var orientationLock = UIInterfaceOrientationMask.all
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return self.orientationLock
}
struct AppUtility {
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")
}
}
Add to the viewcontroller that you want to force an orientation:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
AppDelegate.AppUtility.lockOrientation(.portrait)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
AppDelegate.AppUtility.lockOrientation(.all)
}
回答5:
Just put this in viewDidAppear:
let value = UIInterfaceOrientation.Portrait.rawValue
UIDevice.currentDevice().setValue(value, forKey: "orientation")
回答6:
Swift 3 Answer:
In the view controller you want to lock the orientation of
override var shouldAutorotate: Bool {
return false
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .portrait
}
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
return .portrait
}
Adapted from how to lock portrait orientation for only main view using swift
来源:https://stackoverflow.com/questions/29950456/how-to-lock-orientation-just-for-one-view-controller