ios - safeAreaLayoutGuide - 横向模式

标签 ios swift autolayout safearealayoutguide

我已经像这样设置了 safeAreaLayoutGuide:

let guide = view.safeAreaLayoutGuide

NSLayoutConstraint.activate([
  topControls.topAnchor.constraint(equalTo: guide.topAnchor, constant: 0)
])

这很好用。但是,当我将设备旋转到横向模式时,没有状态栏(电池、信号等)并且屏幕顶部的偏移量为零。这是正确的,基于 anchor 。然而,它看起来并不好。如何在创建 anchor 期间为景观添加偏移量 20?我不想手动更改基于方向的常量。

最佳答案

假设您在 iPhone 上运行,那么这是预期的行为,可以通过覆盖以下内容来更改:

override var prefersStatusBarHidden: Bool {
    return false
}

根据该 UIViewController 方法的描述:

By default, this method returns false with one exception. For apps linked against iOS 8 or later, this method returns true if the view controller is in a vertically compact environment.

如果您覆盖它,那么您将获得一个横向状态栏,并且安全区域指南将相应地进行调整。

编辑

所以对原来的要求有点误解。不是显示状态栏,而是像有状态栏一样有空隙。

这将需要手动完成,因为您无法手动设置仅适用于特定方向/尺寸类别的约束。

这是一个基本的 UIViewController,可以满足您的需求:

class ViewController: UIViewController {
    var testView: UIView!
    var landscapeConstraint: NSLayoutConstraint!
    var portraitConstraint: NSLayoutConstraint!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        self.testView = UIView()
        self.testView.backgroundColor = .green
        self.view.addSubview(self.testView)
        self.testView.translatesAutoresizingMaskIntoConstraints = false

        let guide = view.safeAreaLayoutGuide

        self.testView.leftAnchor.constraint(equalTo: guide.leftAnchor, constant: 0).isActive = true
        self.testView.rightAnchor.constraint(equalTo: guide.rightAnchor, constant: 0).isActive = true
        self.testView.bottomAnchor.constraint(equalTo: guide.bottomAnchor, constant: 0).isActive = true

        self.portraitConstraint = self.testView.topAnchor.constraint(equalTo: guide.topAnchor, constant: 0)
        self.landscapeConstraint = self.testView.topAnchor.constraint(equalTo: guide.topAnchor, constant: 20) // Hardcoded the size but this can be anything you want.

        switch self.traitCollection.verticalSizeClass {
        case .compact:
            self.landscapeConstraint.isActive = true
        case.regular:
            self.portraitConstraint.isActive = true
        default: // This shouldn't happen but let's assume regular (i.e. portrait)
            self.portraitConstraint.isActive = true
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
        super.willTransition(to: newCollection, with: coordinator)

        switch newCollection.verticalSizeClass {
        case .compact:
            self.portraitConstraint.isActive = false
            self.landscapeConstraint.isActive = true
        case.regular:
            self.landscapeConstraint.isActive = false
            self.portraitConstraint.isActive = true
        default: // This shouldn't happen but let's assume regular (i.e. portrait)
            self.landscapeConstraint.isActive = false
            self.portraitConstraint.isActive = true
        }
    }
}

基本上,您设置固定约束,即左侧、右侧和底部,然后设置默认情况下禁用的纵向和横向(常规和紧凑垂直尺寸类)约束。 然后根据当前的方向/尺寸等级决定激活哪一个。 然后你覆盖:

willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator)

基于新的方向/大小类的方法和交换两个约束的事件状态。

需要注意的一件事是始终先停用约束,然后再激活约束,以避免任何提示无法满足的约束。

关于ios - safeAreaLayoutGuide - 横向模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48049297/

相关文章:

ios - App 进入 App Store 且 Container 处于生产模式后,是否可以在 CloudKit 中更改数据模型?

ios - 在日历 View iOS上显示事件标签/字符串?

cocoa - 文本字段的初始大小错误(NSTableView)

ios - 自动布局和同心较小的嵌套 UIImageView

ios - 自动布局和编程约束 : How to deal with updateConstraints firing multiple times?

ios - 如何在完成 block 之前解决嵌套的异步调用

ios - NSDictionary 的 NSArray 上的 NSPredicate

ios - 获取 Twitter 成员列表

swift - 添加 UILabel 强制 UICollectionViewCell 缩小宽度

swift - 计算属性(仅限可获取的属性)与存储属性的优势