假设您有两个希望以两种方式之一水平UIViews
布局:
例如#1代码将是:
// #1
let view1 = UIView()
view1.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(view1)
let view2 = UIView()
view2.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(view2)
// #2
let margins = view.layoutMarginsGuide
view.addLayoutGuide(margins)
view1.leadingAnchor.constraint(equalTo: margins.leadingAnchor, constant: 20).isActive = true
// #3
view2.leadingAnchor.constraint(equalTo: view1.trailingAnchor, constant: 20).isActive = true
// #4
view1.widthAnchor.constraint(equalToConstant: 100).isActive = true
view2.widthAnchor.constraint(equalToConstant: 100).isActive = true
注释 #1:请注意,您不需要给每个视图一个框架,但您需要将自动调整大小的掩码设置为 false。这是许多新程序员忘记的错误。
评论 #2:所有UIViewController
主视图都有一个layoutMarginGuide
在垂直和水平方向上产生标准边距(在 iOS 11 中,特别是对于 iPhone X,有一个新safeAreaLayoutGuide
的垂直对齐方式)。我已将 的前沿设置为view1
的前沿,并在margin
其中增加 20 个点的附加常数。
评论 #3:就像我与 相关view1
,margin
我与view2
view2 view1, but this time the leading edge of
view1`is 20 points from the
后缘相关。
注释#4:对于水平放置,您需要做的最后一件事是给每个视图一个宽度。在这种情况下,我希望两者都是 100 分。
示例 #2 几乎使用与示例 #1 相同的代码,因此我将仅说明关键差异:
let view1 = UIView()
view1.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(view1)
let view2 = UIView()
view2.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(view2)
let margins = view.layoutMarginsGuide
view.addLayoutGuide(margins)
// #1
let spacer1 = UILayoutGuide()
view.addLayoutGuide(spacer1)
let spacer2 = UILayoutGuide()
view.addLayoutGuide(spacer2)
let spacer3 = UILayoutGuide()
view.addLayoutGuide(spacer3)
// #2
spacer.leadingAnchor.constraint(equalTo: margins.leadingAnchor).isActive = true
view1.leadingAnchor.constraint(equalTo: spacer1.trailingAnchor).isActive = true
spacer2.leadingAnchor.constraint(equalTo: view1.trailingAnchor).isActive = true
view2.leadingAnchor.constraint(equalTo: spacer2.trailingAnchor).isActive = true
spacer3.leadingAnchor.constraint(equalTo: view2.trailingAnchor).isActive = true
spacer3.trailingAnchor.constraint(equalTo: margins.trailingAnchor).isActive = true
// #3
view1.widthAnchor.constraint(equalToConstant: 100).isActive = true
view2.widthAnchor.constraint(equalToConstant: 100).isActive = true
spacer1.widthAnchor.constraint(equalTo: spacer2.widthAnchor).isActive = true
spacer2.widthAnchor.constraint(equalTo: spacer3.widthAnchor).isActive = true
评论 #1:在 iOS 9 中,Apple 引入了UILayoutGuides
. 在此之前,要创建“间隔”,您必须实际创建一个不可见的UIView
并将其添加为子视图(以及与之相关的所有开销)。布局指南“行为”类似于视图,但没有这种开销。
注释 #2:如果“margin...spacer1...view1...spacer2...view2...spacer3...margin”的水平序列。请注意,我没有使用任何常量,因为我希望让布局引擎给出相等的间距。
评论 #3:虽然我为两个视图提供宽度值,但我不使用垫片。相反,我声明它们的宽度相等。
请注意,我只使用了水平约束。要使自动布局起作用,您还需要声明垂直约束。大多数概念是相同的......而不是前导/尾随、centerX 和宽度锚,您有顶部/底部、centerY 和高度锚。但!从 iOS 11 开始,您现在safeAreaLayoutGuide
应该使用 . 而不是layoutMarginsGuide
. 这仅适用于垂直!这就是我分开东西的原因。这是我用来处理垂直对齐的代码:
let layoutGuideTop = UILayoutGuide()
let layoutGuideBottom = UILayoutGuide()
view.addLayoutGuide(layoutGuideTop)
view.addLayoutGuide(layoutGuideBottom)
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
}
现在您已经拥有layoutGuideTop
并且layoutGuideBottom
无论运行什么 iOS 版本,它都应该可以工作。