在代码中为元素的动态数量设置约束

Set constraints in code for dynamic number of elements

在我看来,我将拥有动态数量的 UILabel,如下所示:

| HEADER  |
| - label |
| - label |
| - label |
| ...     |
| BUTTON  |

由于标签的数量是动态的,我正在为代码中的每个元素构建带有约束的布局(使用 Snap Kit)。假设我有一个字符串数组,我为数组中的每个字符串创建单独的标签,添加到 superview 并将其定位在前一个字符串的下方。但是我不确定如何为这些标签正确设置约束?我相信我需要写 for-loop,但是如何指示第一个标签粘贴到 header,每个下一个标签粘贴到前一个标签,最后下面的按钮粘贴到最后一个标签?

    header.snp.makeConstraints { (make) -> Void in
        make.top.equalTo(self.view).offset(10)
        make.leading.equalTo(self.view).offset(10)
        make.trailing.equalTo(self.view).offset(10)
    }

    for object in objects {
       let label = UILabel()
       label.text = object
       self.view.addSubview(label)

       // and here how to set correct constraints for each label?
    }

    button.snp.makeConstraints { (make) -> Void in
        make.leading.equalTo(self.view).offset(10)
        make.trailing.equalTo(self.view).offset(10)
        make.bottom.equalTo(self.view).offset(10)
    }

这是我第一次在代码中编写所有约束,如果这听起来像是愚蠢的问题,我很抱歉。感谢您的帮助。

使用垂直堆栈视图。它会让你的生活更轻松 (UIStackView 文档 here

您可以在 for 循环之前声明一个变量来跟踪当前的顶视图。一开始它会指向 header 然后在循环中的每次迭代中更新它:

var topView = header
for object in objects {
    let label = UILabel()
    label.text = object
    self.view.addSubview(label)

    // and here are your constraints
    label.top.equalTo(topView).offset(10)
    label.left.equalTo(self.view).offset(20)

    // topView is now the current label
    topView = label
}

button.snp.makeConstraints { (make) -> Void in
    make.leading.equalTo(self.view).offset(10)
    make.trailing.equalTo(self.view).offset(10)
    make.top.equalTo(topView).offset(10)
    make.bottom.equalTo(self.view).offset(10)
}

如果您的标签具有相同的间距,那么更优选的方法是尝试 UIStackView。您声明一个堆栈视图,为其指定约束,然后在 for 循环中您只需通过 stackView.addArrangedSubview(label)

添加标签