使用NSLayoutAnchor在两个标签之间创建约束?

时间:2017-09-28 20:36:27

标签: ios swift autolayout nslayoutconstraint nslayoutanchor

我以编程方式创建视图,需要在两个标签之间设置约束。我最近刚刚发现了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

您如何在两个标签之间设置约束?

1 个答案:

答案 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:就像我将view1margin相关联一样,我将view2view1, 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