如何使用 swift 中的格式字符串将多个元素对齐到一个主要元素

How to align multiple elements to one main element with format strings in swift

我正在尝试执行下图显示的以下任务

这是我到目前为止的约束,"Entertainment" 字符串由 categoryLabel 表示,"Disney: build it frozen" 由 nameLabel.

addConstraints(withFormat: "H:|-8-[v0(90)]-8-[v1]-8-|", views: imageView, nameLabel)
addConstraints(withFormat: "V:|-8-[v0(90)]", views: imageView)

addConstraints(withFormat: "H:[v0]-8-[v1]", views: imageView, nameLabel)
addConstraints(withFormat: "V:|-8-[v0]-8-[v1]", views: nameLabel, categoryLabel)

func addConstraints(withFormat format: String, views: UIView...) {
    var viewsDictionary = [String: UIView]()
    for (index, view) in views.enumerated() {
        let key = "v\(index)"
        view.translatesAutoresizingMaskIntoConstraints = false
        viewsDictionary[key] = view
    }

    addConstraints(NSLayoutConstraint.constraints(withVisualFormat: format, options: NSLayoutFormatOptions(), metrics: nil, views: viewsDictionary))
}

我遇到的问题是如何将 "categorylabel" 添加到约束中,使其与 imageView 右侧对齐 8 个像素,并在 nameLabel 正下方对齐 8 个像素。正如您从屏幕截图中看到的那样,我可以将它放在 nameLabel 下方,但我很难做到 "categorylabel" 也位于图像视图的右侧。

任何提示将不胜感激:)

我想要的样子

不幸的是,通过将 NSLayoutConstraint.constraints 包装在您自己的函数中,您无法访问所需的功能,即指定 .alignAllLeading NSLayoutFormatOptions 到您的 nameLabel-category约束。

本质上,你需要的是:

NSLayoutConstraint.constraints(withVisualFormat: "V:|-8-[v0]-8-[v1]", options: .alignAllLeading, metrics: nil, views: viewsDictionary))

这将告诉自动布局您希望两个项目的前缘对齐并垂直分隔 8。由于您的名称字段已相对于图像视图的边缘定位,因此这将放置您的类别您想要的字段。

您可以 re-factor 您的 addConstraints 函数接受 NSLayoutFormatOptions:

func addConstraints(withFormat format: String, options: NSLayoutFormatOptions = NSLayoutFormatOptions(), views: UIView...) {

var viewsDictionary = [String: UIView]()
    for (index, view) in views.enumerated() {
        let key = "v\(index)"
        view.translatesAutoresizingMaskIntoConstraints = false
        viewsDictionary[key] = view
    }

    addConstraints(NSLayoutConstraint.constraints(withVisualFormat: format, options: options, metrics: nil, views: viewsDictionary))
}

然后调用它:

addConstraints(withFormat: "V:|-8-[v0]-8-[v1]", options: .alignAllLeading, views: nameLabel, categoryLabel)

顺便说一句,您不需要使用故事板来使用堆栈视图。