如何使用swift仅锁定主视图的纵向方向

Mon*_*WTF 39 ios swift

我使用swift为iPhone创建了一个应用程序,它由嵌入在导航控制器中的许多视图组成.我想将主视图锁定为纵向方向,并且仅锁定横向方向的导航控制器的子视图.这是我的意思的一个例子:

  • UINavigationController的
    • UiViewController1(纵向锁定)初始视图控制器,导航栏上有一个按钮,可以让用户访问可以选择其他视图的列表
    • UIViewController2(景观锁定)
    • UiViewController3(人像与风景)
    • UiViewController4(人像与风景)
    • ...
    • ...

我怎样才能做到这一点?

Jas*_*son 49

按照斯威夫特苹果文档supportedInterfaceOrientations:

讨论

当用户更改设备方向时,系统会在根视图控制器或填充窗口的最顶层显示的视图控制器上调用此方法.如果视图控制器支持新方向,则窗口和视图控制器将旋转到新方向.仅当视图控制器的shouldAutorotate方法返回true时才调用此方法.

您的导航控制器应覆盖shouldAutorotatesupportedInterfaceOrientations如下所示.UINavigationController为了方便,我在扩展中做了这个:

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

    public override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
        return (visibleViewController?.supportedInterfaceOrientations())!
    }
}
Run Code Online (Sandbox Code Playgroud)

而你的主视图控制器(任何时候都是肖像)应该具有:

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.Portrait
}
Run Code Online (Sandbox Code Playgroud)

然后,在您要支持纵向或横向的子视图控制器中:

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.All
}
Run Code Online (Sandbox Code Playgroud)

编辑:针对iOS 9更新:-)

  • 当视图嵌入导航控制器时,我遇到了问题,例如,如果我想要两个视图,第一个是纵向,第二个是横向,在同一个导航控制器下,代码不起作用. (3认同)
  • 快速说明:`toRaw()`已被最新的Swift中的`rawValue`取代. (3认同)
  • 正如 Regis 上面所说:新的函数签名需要 UIInterfaceOrientationMask 的返回值。这意味着现在正确的答案是:`override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask { return UIInterfaceOrientationMask.Portrait }` (2认同)
  • 我认为它在 iOS9 中不起作用。你能确认一下吗? (2认同)
  • Swift 3 将这些从 func 更改为 var getter。只需将 func 更改为 var (2认同)

bmj*_*hns 17

还回答了[这里]

当您拥有复杂的视图层次结构时,例如拥有多个导航控制器和/或选项卡视图控制器,事情就会变得非常混乱.

此实现将其置于各个视图控制器上以设置何时锁定方向,而不是依靠App Delegate通过迭代子视图或依赖继承来查找它们.

斯威夫特3

在AppDelegate中:

/// set orientations you want to be allowed in this property by default
var orientationLock = UIInterfaceOrientationMask.all

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        return self.orientationLock
}
Run Code Online (Sandbox Code Playgroud)

在其他一些全局struct或helper类中,我在这里创建了AppUtility:

struct AppUtility {

    static func lockOrientation(_ orientation: UIInterfaceOrientationMask) {

        if let delegate = UIApplication.shared.delegate as? AppDelegate {
            delegate.orientationLock = orientation
        }
    }

    /// OPTIONAL Added method to adjust lock and rotate to the desired orientation
    static func lockOrientation(_ orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation:UIInterfaceOrientation) {

        self.lockOrientation(orientation)

        UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation")
    }

}
Run Code Online (Sandbox Code Playgroud)

然后在所需的ViewController中,您想要锁定方向:

 override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    AppUtility.lockOrientation(.portrait)
    // Or to rotate and lock
    // AppUtility.lockOrientation(.portrait, andRotateTo: .portrait)

}

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

    // Don't forget to reset when view is being removed
    AppUtility.lockOrientation(.all)
}
Run Code Online (Sandbox Code Playgroud)

  • 请不要在多个问题中添加[相同答案](http://stackoverflow.com/a/41811798/4687348)。回答最好的一个并将其余的标记为重复。请参阅[是否可以为多个问题添加重复的答案?](http://meta.stackexchange.com/q/104227/347985) (2认同)

UIR*_*der 13

如果您的视图嵌入在storyboard中的navigationcontroller中,则导航控制器委托UINavigationControllerDelegate并添加以下方法

class ViewController: UIViewController, UINavigationControllerDelegate {
    func navigationControllerSupportedInterfaceOrientations(navigationController: UINavigationController) -> UIInterfaceOrientationMask {
        return UIInterfaceOrientationMask.Portrait
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 6

重要的想法是在 AppDelegate 中描述整个应用程序支持的界面方向。例如,要阻止所有视图到纵向,只需执行以下操作:

  func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask{
    return UIInterfaceOrientationMask.portrait
}
Run Code Online (Sandbox Code Playgroud)

很多人只是通过谷歌搜索来寻找这个答案,所以我希望你能原谅我。

适用于 Swift 3.0


sup*_*org 6

更新:如果你有设置方向向右麻烦启动应用在后iOS 10,尽量做到在ObjC代替Swift,并用class MyNavigationController: MyNavigationControllerBase:

@implementation ABNavigationControllerBase
- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}
@end
Run Code Online (Sandbox Code Playgroud)

斯威夫特3:

class MyNavigationController: UINavigationController {
    override func viewDidLoad() {
        super.viewDidLoad()
        UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")
    }
    override var shouldAutorotate: Bool {
        return false
    }
    override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return .portrait
    }
    override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
        return .portrait
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 6

Swift 4.2+中使用相同的JasonJasonJason答案(在iOS 11上正常工作)

1-覆盖应该如下所示自动旋转和supportedInterfaceOrientations。

extension UINavigationController {

open override var shouldAutorotate: Bool {
    return true
}

open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return (visibleViewController?.supportedInterfaceOrientations)!
    }
}
Run Code Online (Sandbox Code Playgroud)

2-并且您的主要ViewController(始终为纵向)应具有:

 public override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.portrait
}
Run Code Online (Sandbox Code Playgroud)

3-然后,在子视图控制器中要支持纵向或横向:

 public override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.all
}
Run Code Online (Sandbox Code Playgroud)


Sah*_*Roy 4

在你想要纵向的主控制器中,

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

self.orientation = UIInterfaceOrientationMaskPortrait;
//Or self.orientation = UIInterfaceOrientationPortraitUpsideDown
}
Run Code Online (Sandbox Code Playgroud)

在 subVC 中你想要使用 Landscape 的地方

  self.orientation =  UIInterfaceOrientationLandscapeLeft:
   self.orientation =  UIInterfaceOrientationLandscapeRight:
Run Code Online (Sandbox Code Playgroud)

或者你可以重写这个方法

- (NSUInteger)supportedInterfaceOrientations
{
  return UIInterfaceOrientationMaskPortrait;
} 
Run Code Online (Sandbox Code Playgroud)

这就是我在 iOS7 中使用 Obj-c 的方式,我认为这段代码也可以在 iOS8 中工作