safeAreaLayoutGuide - 横向模式
Posted
技术标签:
【中文标题】safeAreaLayoutGuide - 横向模式【英文标题】:safeAreaLayoutGuide - landscape mode 【发布时间】:2018-01-01 11:33:20 【问题描述】:我已经这样设置了 safeAreaLayoutGuide:
let guide = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
topControls.topAnchor.constraint(equalTo: guide.topAnchor, constant: 0)
])
这很好用。但是,当我将设备旋转到横向模式时,没有状态栏(电池、信号等),并且与屏幕顶部的偏移为零。这是正确的,基于锚。但是,它看起来并不好。如何在锚点创建期间为景观添加偏移量 20?我不想手动更改基于方向的常量。
【问题讨论】:
【参考方案1】:假设您在 iPhone 上运行,那么这是预期的行为,可以通过覆盖以下内容进行更改:
override var prefersStatusBarHidden: Bool
return false
从那个 UIViewController 方法的描述:
默认情况下,此方法返回 false,但有一个异常。对于应用程序 链接到 ios 8 或更高版本,如果视图,此方法返回 true 控制器处于垂直紧凑的环境中。
如果您覆盖它,那么您将获得一个横向的状态栏,并且安全区域指南将相应地进行调整。
编辑
所以对原始要求有一点误解。不是显示状态栏,而是有一个间隙,就像有状态栏一样。
这需要手动完成,因为您无法手动设置仅适用于某些方向/尺寸类别的约束。
这是一个基本的 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)
基于新的方向/大小类的方法和交换两个约束的活动状态。
需要注意的一点是始终先停用约束,然后再激活约束,以避免任何抱怨无法满足的约束。
【讨论】:
这是一个“半解决方案”。横向模式下的状态栏不是很常见。 对不起,我不明白。你是什么意思'横向模式下的状态栏不是很频繁'?您是否不想要状态栏,但仍然与顶部之间存在差距? 是...有差距,但没有状态栏 好的,知道了。好吧,您将不得不手动执行此操作,因为您无法设置仅适用于一个方向或另一个方向的约束,您应该真正谈论尺寸类别而不是方向。我将用您可以采取的一种方法更新我的答案。 谢谢。手动更改约束有所帮助。它没有我担心的代码那么糟糕:-)以上是关于safeAreaLayoutGuide - 横向模式的主要内容,如果未能解决你的问题,请参考以下文章
如何修复 - safeAreaLayoutGuide' 仅适用于 iOS 11.0 或更高版本