安全区,特别是safeAreaLayoutGuide,与约束有关。
有多种方法可以编写自动布局约束(Visual Format Layout 或 VFL,显式 - 和冗长 - NSLayoutConstraints),但我更喜欢使用“布局锚点”。
任何布局的基本思想都是position和size。给某个东西一个宽度/高度和 x/y 轴值,你就知道了。很像框架。
所以基本的“锚”布局方式:
micButton.frame = CGRect.init(x: self.tabBar.center.x - 62, y: self.view.bounds.height - 94, width: 124, height: 124)
会是这样的:
let micButton = UIButton()
micButton.translatesAutoresizingMaskIntoConstraints = false
micButton.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -94).isActive = true
micButton.widthAnchor.constraint(equalToConstant: 124).isActive = true
micButton.heightAnchor.constraint(equalToConstant: 124).isActive = true
micButton.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: -62).isActive = true
一些注意事项:
- 是的,您不指定框架。实际上,您只是在可能的情况下进行初始化。
- 由于您没有使用 IB,因此您需要将自动调整大小掩码标志设置为 false。即使是最有经验的开发人员有时也会忘记这一点。 (这样做通常意味着您会得到“意想不到的”结果,从看不到东西到看到它放错了位置。)
- 我设置了底部或 Y 轴、宽度和高度,最后是 X 轴。
虽然它比使用框架需要更多代码,但您获得的是跨屏幕尺寸的一致性。
但您想要更多 - 您需要为 iPhone X 安全区域编写代码。你有两个 Apple 给你的工具:layoutMarginsGuide 和 safeAreaLayoutGuide。前者是在 iOS 9 中引入的(以及更简单的 layoutGuide 和布局锚点),而后者是在 iOS 11 中引入的。
[我的假设可能是一个安全的假设,即所有 iPhone X 设备都将运行 iOS 11 或更高版本。由于“安全区域”实际上只需要此设备,因此您需要以下内容。]
边距适用于 所有 设备,用于前/后(或水平)边缘。它们也适用于顶部/底部(或垂直)边缘。但对于 iPhone X,您需要关注不同的顶部/底部,即“安全区域”。
let layoutGuideTop = UILayoutGuide()
let layoutGuideBottom = UILayoutGuide()
view.addLayoutGuide(layoutGuideTop)
view.addLayoutGuide(layoutGuideBottom)
let margins = view.layoutMarginsGuide
view.addLayoutGuide(margins)
if #available(iOS 11, *) {
let guide = view.safeAreaLayoutGuide
layoutGuideTop.topAnchor.constraintEqualToSystemSpacingBelow(guide.topAnchor, multiplier: 1.0).isActive = true
layoutGuideBottom.bottomAnchor.constraintEqualToSystemSpacingBelow(guide.bottomAnchor, multiplier: 1.0).isActive = true
} else {
layoutGuideTop.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor).isActive = true
layoutGuideBottom.bottomAnchor.constraint(equalTo: bottomLayoutGuide.topAnchor).isActive = true
}
上面的代码 sn-p 将根据 iOS 版本生成正确的顶部/底部边距变量(layoutGuideTop 和 layoutGuideBottom)。从那里您可以将底部锚点调整为:
micButton.bottomAnchor.constraint(equalTo: laytouGuideBottom, constant: -94).isActive = true
应该将micButton 设置为高于底部安全区域 94 点。
这里有一些链接可以帮助您进行布局锚点和指南:
Layout Anchors
Layout Guides
Safe Area Layout Guides
编辑:
关于约束的最后一点说明。由于您不依赖帧值,所有这些代码最好放在viewDidLoad 中,因为布局引擎会适当地确定所有内容(并且viewDidLayoutSubviews 可能会被多次调用)。