如何使用 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)
顺便说一句,您不需要使用故事板来使用堆栈视图。
我正在尝试执行下图显示的以下任务
这是我到目前为止的约束,"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)
顺便说一句,您不需要使用故事板来使用堆栈视图。