使用Swift在一个ViewController中强制使用横向模式

问题描述 投票:53回答:15

我试图在我的应用程序中强制只有一个视图在横向模式,我打电话

override func shouldAutorotate() -> Bool {
    print("shouldAutorotate")
    return false
}

override func supportedInterfaceOrientations() -> Int {
    print("supportedInterfaceOrientations")
    return Int(UIInterfaceOrientationMask.LandscapeLeft.rawValue)
}

override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
    return UIInterfaceOrientation.LandscapeLeft
}

视图以纵向模式启动,并在更改设备方向时保持旋转。 永远不会调用shouldAutorotate。 任何帮助,将不胜感激。

ios swift landscape
15个回答
62
投票

它可能对其他人有用,我找到了一种强制视图以横向模式启动的方法:

把它放在viewDidLoad()中:

let value = UIInterfaceOrientation.landscapeLeft.rawValue
UIDevice.current.setValue(value, forKey: "orientation")

和,

override var shouldAutorotate: Bool {
    return true
}

1
投票

在ViewDtroller中的viewDidLoad方法调用下面的函数

func rotateDevice(){
    UIDevice.current.setValue(UIInterfaceOrientation.landscapeLeft.rawValue, forKey: "orientation")
    UIView.setAnimationsEnabled(true) // while rotating device it will perform the rotation animation
}`

应用程序代理文件添加以下功能和变量

//Orientation Variables
var orientationLock = UIInterfaceOrientationMask.portrait
var myOrientation: UIInterfaceOrientationMask = .portrait

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { return .landscape }

0
投票

根据documentation of supportedInterfaceOrientationsshouldAutorotate方法应该返回Objective-C中的trueYES,以便考虑supportedInterfaceOrientations


0
投票

我的解决方案是

刚刚在AppDelegate中添加了以下代码

enum PossibleOrientations {
  case portrait
    case landscape

    func o() -> UIInterfaceOrientationMask {
      switch self {
      case .portrait:
        return .portrait
      case .landscape:
        return .landscapeRight
      }
    }
}
var orientation: UIInterfaceOrientationMask = .portrait

func switchOrientation(to: PossibleOrientations) {
    let keyOrientation = "orientation"

    if to == .portrait && UIDevice.current.orientation.isPortrait {
        return
    } else if to == .landscape && UIDevice.current.orientation.isLandscape {
        return
    }

    switch to {
    case .portrait:
        orientation = .portrait
        UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: keyOrientation)
    case .landscape:
        orientation = .landscapeRight
        UIDevice.current.setValue(UIInterfaceOrientation.landscapeRight.rawValue, forKey: keyOrientation)
    }
}

并调用以下代码进行更改

override func viewDidLoad() {
    super.viewDidLoad()

    if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
        appDelegate.switchOrientation(to: .landscape)
    }
}

或者如下

@IBAction func actBack() {
    if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
        appDelegate.switchOrientation(to: .portrait)
    }
    self.navigationController?.popViewController(animated: true)
}

0
投票
// below code put in view controller
// you can change landscapeLeft or portrait

override func viewWillAppear(_ animated: Bool) {
        UIDevice.current.setValue(UIInterfaceOrientation.landscapeRight.rawValue, forKey: "orientation")
    }

override var shouldAutorotate: Bool {
        return true
    }
    override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return .landscapeRight
    }
    override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
        return .landscapeRight
    }

0
投票

在AppDelegate中添加此内容

//Orientation Variables
    var myOrientation: UIInterfaceOrientationMask = .portrait

    func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask
    {
        return myOrientation

    }

在viewController中添加,想要更改方向

override func viewDidLoad() {
        super.viewDidLoad()
        self.rotateToLandsScapeDevice()
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        self.rotateToPotraitScapeDevice()
    }

    func rotateToLandsScapeDevice(){
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        appDelegate.myOrientation = .landscapeLeft
        UIDevice.current.setValue(UIInterfaceOrientation.landscapeLeft.rawValue, forKey: "orientation")
        UIView.setAnimationsEnabled(true)
    }

    func rotateToPotraitScapeDevice(){
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        appDelegate.myOrientation = .portrait
        UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
        UIView.setAnimationsEnabled(true)
    }

-3
投票
class CustomUIViewController : UIViewController{

    override var   supportedInterfaceOrientations : UIInterfaceOrientationMask{

        return  .landscapeLeft

    }

}


class ViewController: CustomUIViewController {
.
.
.
}

46
投票

斯威夫特4

override func viewDidLoad() {
    super.viewDidLoad()
    let value = UIInterfaceOrientation.landscapeLeft.rawValue
    UIDevice.current.setValue(value, forKey: "orientation")
}

override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return .landscapeLeft
}

override var shouldAutorotate: Bool {
    return true
}

//如果您的视图嵌入在导航控制器中,则仅上述操作无效。你必须级联//所以在类定义后添加以下扩展名

extension UINavigationController {

override open var shouldAutorotate: Bool {
    get {
        if let visibleVC = visibleViewController {
            return visibleVC.shouldAutorotate
        }
        return super.shouldAutorotate
    }
}

override open var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation{
    get {
        if let visibleVC = visibleViewController {
            return visibleVC.preferredInterfaceOrientationForPresentation
        }
        return super.preferredInterfaceOrientationForPresentation
    }
}

override open var supportedInterfaceOrientations: UIInterfaceOrientationMask{
    get {
        if let visibleVC = visibleViewController {
            return visibleVC.supportedInterfaceOrientations
        }
        return super.supportedInterfaceOrientations
    }
}}

斯威夫特3

override func viewDidLoad() {
    super.viewDidLoad()
    let value = UIInterfaceOrientation.landscapeLeft.rawValue
    UIDevice.current.setValue(value, forKey: "orientation")
}

private func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.landscapeLeft
}

private func shouldAutorotate() -> Bool {
    return true
}

20
投票

Swift 4,在iOS 11中测试过

您可以在projectTarget中指定方向 - >常规 - > DeploymentInfo(设备方向) - >纵向(Landscapeleft和Landscaperight是可选的)

AppDelegate中

    var myOrientation: UIInterfaceOrientationMask = .portrait
    func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        return myOrientation
    }

LandScpaeViewController

override func viewDidLoad() {
        super.viewDidLoad()
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        appDelegate.myOrientation = .landscape
}

OnDismissButtonTap

let appDelegate = UIApplication.shared.delegate as! AppDelegate
 appDelegate.myOrientation = .portrait

而已。 :)


18
投票

使用Swift 2.2

尝试:

let value = UIInterfaceOrientation.LandscapeLeft.rawValue
UIDevice.currentDevice().setValue(value, forKey: "orientation")

其次是:

UIViewController.attemptRotationToDeviceOrientation()

来自Apple的UIViewController类参考:

某些视图控制器可能希望使用特定于应用程序的条件来确定支持哪些接口方向。如果您的视图控制器执行此操作,当这些条件发生更改时,您的应用程序应调用此类方法。系统立即尝试旋转到新方向。

然后,正如其他人建议的那样,根据需要覆盖以下方法:

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.LandscapeLeft
}

override func shouldAutorotate() -> Bool {
    return true
}

我有一个签名视图的类似问题,这解决了我。


9
投票

对我来说,最好的结果来自Zeesha的答案和sazz的答案。

将以下行添加到AppDelegate.swift:

var orientationLock = UIInterfaceOrientationMask.portrait
var myOrientation: UIInterfaceOrientationMask = .portrait
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
    return myOrientation
}  

将以下行添加到视图控制器类:

let appDel = UIApplication.shared.delegate as! AppDelegate

将以下行添加到视图控制器的viewDidLoad()

appDel.myOrientation = .landscape
UIDevice.current.setValue(UIInterfaceOrientation.landscapeLeft.rawValue, forKey: "orientation")

(可选)将此行添加到您的解散功能:

appDel.myOrientation = .portrait
UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")

这些代码行的作用是将默认方向设置为纵向,在视图控制器加载时将其旋转,然后在视图控制器关闭后最终将其重置为纵向。


6
投票

我需要强制一个控制器进入纵向。添加这个对我有用。

iOS 11的swift 4

override var   supportedInterfaceOrientations : UIInterfaceOrientationMask{

    return  .portrait

}

2
投票

适用于Swift 2.2

 func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
    if self.window?.rootViewController?.presentedViewController is SignatureViewController {

        let secondController = self.window!.rootViewController!.presentedViewController as! SignatureViewController

        if secondController.isPresented {

            return UIInterfaceOrientationMask.LandscapeLeft;

        } else {

            return UIInterfaceOrientationMask.Portrait;
        }

    } else {

        return UIInterfaceOrientationMask.Portrait;
    }
}

2
投票

Swift 3.这会在每次用户重新打开应用程序时锁定方向。

class MyViewController: UIViewController {
    ...
    override func viewDidLoad() {
        super.viewDidLoad()

        // Receive notification when app is brought to foreground
        NotificationCenter.default.addObserver(self, selector: #selector(self.onDidBecomeActive), name: NSNotification.Name.UIApplicationDidBecomeActive, object: nil)
    }

    // Handle notification
    func onDidBecomeActive() {
        setOrientationLandscape()
    }

    // Change orientation to landscape
    private func setOrientationLandscape() {
        if !UIDevice.current.orientation.isLandscape {
            let value = UIInterfaceOrientation.landscapeLeft.rawValue
            UIDevice.current.setValue(value, forKey:"orientation")
            UIViewController.attemptRotationToDeviceOrientation()
        }
    }

    // Only allow landscape left
    override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return UIInterfaceOrientationMask.landscapeLeft
    }

    /*
    // Allow rotation - this seems unnecessary
    private func shouldAutoRotate() -> Bool {
        return true
    }
    */
    ...
}

1
投票

斯威夫特4

试图保持方向没有任何效果,但这对我来说:

...        
override func viewDidLoad() {
       super.viewDidLoad()
       forcelandscapeRight()
       let notificationCenter = NotificationCenter.default
       notificationCenter.addObserver(self, selector: #selector(forcelandscapeRight), name: Notification.Name.UIDeviceOrientationDidChange, object: nil)
    }

    @objc func forcelandscapeRight() {
        let value = UIInterfaceOrientation.landscapeRight.rawValue
        UIDevice.current.setValue(value, forKey: "orientation")
    }
....
© www.soinside.com 2019 - 2024. All rights reserved.