【问题标题】:Using NSLayoutAnchor to create constraints between two labels?使用 NSLayoutAnchor 在两个标签之间创建约束?
【发布时间】:2017-09-28 20:36:26
【问题描述】:

我正在以编程方式创建视图,需要在两个标签之间设置约束。我最近刚刚发现了 NSLayoutAnchor 并觉得使用它是一个不错的选择,但我不确定如何在两个不同的事物(即标签、图像视图等)之间创建约束。我知道一般设置如下所示:

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

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

【问题讨论】:

    标签: ios swift autolayout nslayoutconstraint nslayoutanchor


    【解决方案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:请注意,您不需要给每个视图一个框架,但您确实需要设置自动将掩码调整为假。这是许多新程序员忘记的错误。

    评论 #2: 所有UIViewController 主视图都有一个layoutMarginGuide,可以在垂直和水平方向产生标准边距(在iOS 11 中,特别是对于iPhone X,有一个新的@987654325 @ 表示垂直对齐)。我已将 view1 的前沿设置为 margin 的前沿,并在其中增加了 20 个点。

    评论 #3: 就像我将 view1 关联到 margin,我将 view2 关联到 view1, but this time the leading edge ofview2is 20 points from theview1` 尾随 em> 边缘。

    评论#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:Apple 在 iOS 9 中引入了UILayoutGuides 的概念。在此之前,要创建“间隔”,您必须实际创建一个不可见的UIView 并将其添加为子视图(以及与之相关的所有开销)。布局指南“行为”类似于视图,但没有这种开销。

    评论#2:如果“margin...spacer1...view1...spacer2...view2...spacer3...margin”的水平序列。请注意,我没有使用任何常量,因为我希望让布局引擎给出相等的间距。

    评论#3:虽然我为两个视图都提供了宽度值,但我不赞成使用垫片。相反,我声明它们的宽度相等。

    请注意,我只使用了 horizo​​ntal 约束。要使自动布局起作用,您还需要声明 vertical 约束。大多数概念是相同的......而不是前导/尾随、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
    }
    

    现在您有了layoutGuideToplayoutGuideBottom,无论运行什么iOS 版本,它们都应该可以工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多