IOS。如何在每个 UIViewController 上启用和禁用旋转?

Posted

技术标签:

【中文标题】IOS。如何在每个 UIViewController 上启用和禁用旋转?【英文标题】:iOS. How to enable and disable rotation on each UIViewController? 【发布时间】:2016-08-16 07:55:16 【问题描述】:

我有一个 UIViewController,我想在不同场景下禁用或启用屏幕旋转

例子:

if flag 
   rotateDevice = false

else 
   rotateDevice = true

我该怎么做?

【问题讨论】:

【参考方案1】:

我有答案。 在AppDelegate,如果你旋转设备,推送视图控制器等。这个函数总是调用

swift 3/4

更新
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask

    return self.restrictRotation

self.restrictRotation 是自定义参数。

使用方法:

在 Appdelegate 中:

 var restrictRotation:UIInterfaceOrientationMask = .portrait

在 ViewController 中:

当 ViewDidLoad 或 viewWillAppear 方法被调用时。我们会这样改变:

(UIApplication.shared.delegate as! AppDelegate).restrictRotation = .all 

然后会调用 AppDelegate 上的这个方法。

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

【讨论】:

这里的self.restrictRotation 是什么?它在哪里被清除? @NileshPol 这是您必须创建的参数。在旋转设备或更改 UIViewController 之前,将调用该函数。 @NileshPol 您必须使用数据类型 UIInterfaceOrientationMask 创建该参数 我按照这个方法,但是有问题。如果您在 .all 视图控制器上处于横向状态,然后您转到一个新的视图控制器(将 viewWillAppear 中的正确代码设置为仅允许 .portrait),则该新视图控制器将保持在横向状态。我会继续寻找解决办法。 谢谢!像魅力一样工作。【参考方案2】:

您只需在您的UIViewController 中实现shouldAutorotatesupportedInterfaceOrientations。看看this documentation。例如:

override func shouldAutorotate() -> Bool 
    return true

您还可以指定可用的方向。这是一个只有纵向方向的示例:

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask 
    return .Landscape

编辑: 如果您想支持关于标志的不同方向,您只需执行以下操作:

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask 
    if myFlag 
        return .Landscape
     else 
        return .All
    

(如果myFlag 为真,则允许Landscape 方向。否则,将允许所有方向)。

【讨论】:

在 Swift 4 中,如果我将函数放在我的视图控制器中,我会得到 Method does not override any method from its superclass @Moondra,swift 4 将它们定义为计算变量而不是函数。使用 Xcode 的代码补全建议 supportedInterfaceOrientations 没有调用【参考方案3】:

斯威夫特 4

override var supportedInterfaceOrientations: UIInterfaceOrientationMask 
    get 
        return .portrait

    

【讨论】:

添加扩展将使答案变得清晰。不仅适用于 OP,也适用于遇到此问题的未来用户。 这是来自 UIViewController 的方法,覆盖它会阻止屏幕旋转【参考方案4】:

在 swift 5 中,与之前一样,如果您想允许(避免其他)特定 UIViewController 以特定方向旋转,您必须在 UIViewController 类中覆盖“supportedInterfaceOrientations”,如下所示:

class MyViewController:UIViewController 
    override var supportedInterfaceOrientations: UIInterfaceOrientationMask 
        return .portrait
    

这里有可能的选项:

public struct UIInterfaceOrientationMask : OptionSet 

    public init(rawValue: UInt)

    
    public static var portrait: UIInterfaceOrientationMask  get 

    public static var landscapeLeft: UIInterfaceOrientationMask  get 

    public static var landscapeRight: UIInterfaceOrientationMask  get 

    public static var portraitUpsideDown: UIInterfaceOrientationMask  get 

    public static var landscape: UIInterfaceOrientationMask  get 

    public static var all: UIInterfaceOrientationMask  get 

    public static var allButUpsideDown: UIInterfaceOrientationMask  get 

扩展

如果您希望能够区分 iPad 或 iPhone,您可以使用 UIUserInterfaceIdiom:

override var supportedInterfaceOrientations: UIInterfaceOrientationMask
    get
        return UIDevice.current.userInterfaceIdiom == .phone ? [.portrait, . portraitUpsideDown]:.all //OBS -> You can also return an array
    

地点:

public enum UIUserInterfaceIdiom : Int 

    
    case unspecified

    @available(ios 3.2, *)
    case phone // iPhone and iPod touch style UI

    @available(iOS 3.2, *)
    case pad // iPad style UI

    @available(iOS 9.0, *)
    case tv // Apple TV style UI

    @available(iOS 9.0, *)
    case carPlay // CarPlay style UI

【讨论】:

您还可以在get 中检查设备类型。假设 iPhone 应该只允许使用此 ViewController 的纵向方向,但 iPad(以及其他任何东西)可以使用每个方向:if UIDevice.current.userInterfaceIdiom == .phone return .portrait else return .all @Neph 好的,在这种情况下你还可以看到我前段时间写的另一个答案***.com/a/53006873/1824565 我更多的是在谈论方向,而不是大小“类型”。 ;) @Neph 我明白你的意思。你可以使用 UIUserInterfaceIdiom 看看我的回答 我是,看我的评论。 ;) 无需像在第一次编辑时那样过度复杂化。【参考方案5】:

AppDelegate 中最常见的请求(iPhone:纵向,iPad:全部)的简单解决方案:

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask 
    return UIDevice.current.userInterfaceIdiom == .phone ? .portrait : .all

【讨论】:

这在许多情况下实际上是一个很好的方法:它适用于整个应用程序,实际上允许根据设备保持不同。正是我想要的。【参考方案6】:

发现这是迄今为止最简单的实现,并且适用于特定的视图控制器。将此添加到 viewController 类,在 viewDidLoad() 之后

override open var shouldAutorotate: Bool 
        return false
    

【讨论】:

【参考方案7】:

斯威夫特 5

override var shouldAutorotate: Bool 
    false

【讨论】:

【参考方案8】:

在 Target -> General -> Deployment Info -> Portrait 中设置设备方向纵向

【讨论】:

这是正确的答案。能够在视图控制器中覆盖自动旋转发生了什么?它曾经是一个函数,现在它是一个 var,当我尝试覆盖它时没有任何效果 - 还没有找到令人满意的答案 否决:这是一个错误的答案,标题是disable rotate on one UIViewController 不适用于整个应用程序。 投反对票,但不低于零 - 这是对不同问题的正确答案,而不是误导性答案。 我个人觉得问题的措辞是“iOS。如何在每个和每个 UIViewController 上启用和禁用旋转?” ...这将是一个合适的答案,因为每个都可以轻松转换为所有视图控制器....它禁用整个应用程序的旋转...我找到了这个整体线程,因为我想为我的整个应用程序禁用旋转,它对我有用,所以这就是为什么我选择对此表示赞成。如果问题更具体,可能不会提及整个回复。任何地方都没有难过的感觉...感谢大家的帮助! 这将影响所有 UIViewControllers

以上是关于IOS。如何在每个 UIViewController 上启用和禁用旋转?的主要内容,如果未能解决你的问题,请参考以下文章

如何更新 Apple 地图中的路线 - iOS 13.0 中的 Xcode Swift 5?

iOS 生命周期 -initviewDidLoadviewWillAppearviewDidAppearviewWillDisappearviewDidDisappear 区别和用途

当 UIViewController 回到顶部时,iOS 中是不是有委托函数来获得通知?

包含 TableView 的 UIViewController 中的 UISearchBar 问题

IOS。如何在每个 UIViewController 上启用和禁用旋转?

如何在核心数据iOS中获取每个实体的最后一个条目