我以编程方式创建视图,需要在两个标签之间设置约束。我最近刚刚发现了NSLayoutAnchor并觉得使用它是一个不错的选择,但我不确定如何在两个不同的东西(即标签,imageViews等)之间创建约束。我知道一般设置看起来像这样:
let codedLabel:UILabel = UILabel()
codedLabel.frame = CGRect(x: 100, y: 100, width: 200, height: 200)
codedLabel.textAlignment = .center
codedLabel.text = alertText
codedLabel.numberOfLines=1
codedLabel.textColor=UIColor.red
codedLabel.font=UIFont.systemFont(ofSize: 22)
codedLabel.backgroundColor=UIColor.lightGray
self.contentView.addSubview(codedLabel)
codedLabel.translatesAutoresizingMaskIntoConstraints = false
codedLabel.heightAnchor.constraint(equalToConstant: 200).isActive = true
codedLabel.widthAnchor.constraint(equalToConstant: 200).isActive = true
codedLabel.centerXAnchor.constraint(equalTo: codedLabel.superview!.centerXAnchor).isActive = true
codedLabel.centerYAnchor.constraint(equalTo: codedLabel.superview!.centerYAnchor).isActive = true
您如何在两个标签之间设置约束?
答案 0 :(得分:1)
假设您有两个UIViews
希望以两种方式之一展示水平:
视图#1是超级视图边缘或安全区域的前沿20点,视图#2是视图#1的另外20个点。 (想想左对齐的按钮行。)
两个视图都要居中,每个视图之前/之间/之后的间距相等。 (想想两个间隔相等且居中的按钮。)
例如#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
与view1, but this time the leading edge of
{2} {{1}联系起来} view1` 尾随边缘。
评论#4: 水平展示位置最后需要做的就是为每个视图提供一个宽度。在这种情况下,我希望两者都是100分。
示例#2几乎使用与示例#1相同的代码,因此我将仅注意关键区别:
is 20 points from the
评论#1:在iOS 9中,Apple引入了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
的概念。在此之前,要创建“间隔符”,您必须实际创建一个不可见的UILayoutGuides
并将其添加为子视图(包含与之关联的所有开销)。布局指南“像行为一样”,但没有这种开销。
评论#2:水平序列,如果“margin ... spacer1 ... view1 ... spacer2 ... view2 ... spacer3 ... margin”。请注意,我不使用任何常量,因为我希望让布局引擎给出相等的间距。
评论#3:虽然我我为两个视图提供宽度值,但我没有使用间隔符。相反,我宣布他们的宽度相等。
请注意,我只使用水平约束。要使自动布局生效,您还需要声明垂直约束。大多数概念都是相同的...而不是前导/尾随,centerX和宽度锚点,你有top / bottom,centerY和height。但!从iOS 11开始,您现在应该使用UIView
而不是safeAreaLayoutGuide
。这仅适用于垂直!这就是我把事情分开的原因。这是我用来处理垂直对齐的代码:
layoutMarginsGuide
现在,无论iOS版本正在运行,您都可以使用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
。