iOS - 在堆栈视图中以编程方式添加垂直线 [英] iOS - Add vertical line programatically inside a stack view
问题描述
我正在尝试以编程方式在堆栈视图内的标签之间添加垂直线.
I'm trying to add vertical lines, between labels inside a stack view all programatically.
所需的饰面如下图所示:
The desired finish will be something like this image:
我可以添加标签,所有标签都具有所需的间距;我可以添加水平线,但我不知道如何在中间添加这些分隔线.
I can add the labels, all with the desired spacing; I can add horizontal lines but I can't figure out how to add those separator vertical lines in-between.
我想这样做:
let stackView = UIStackView(arrangedSubviews: [label1, verticalLine, label2, verticalLine, label3])
有什么提示吗?
谢谢
推荐答案
您不能在两个地方使用同一个视图,因此您需要创建两个单独的垂直线视图.您需要像这样配置每个垂直线视图:
You can't use the same view in two places, so you'll need to create two separate vertical line views. You need to configure each vertical line view like this:
- 设置其背景颜色.
- 将其宽度限制为 1(这样您会得到一条线,而不是矩形).
- 限制它的高度(所以它不会被拉伸到堆栈视图的整个高度).
因此一次将一个标签添加到堆栈视图中,并在将每个标签添加到堆栈视图之前执行以下操作:
So add the labels one at a time to the stack view, and do something like this before adding each label to the stack view:
if stackView.arrangedSubviews.count > 0 {
let separator = UIView()
separator.widthAnchor.constraint(equalToConstant: 1).isActive = true
separator.backgroundColor = .black
stackView.addArrangedSubview(separator)
separator.heightAnchor.constraint(equalTo: stackView.heightAnchor, multiplier: 0.6).isActive = true
}
请注意,您不希望垂直线与标签的宽度相同,因此您必须不设置distribution
属性fillEqually
的堆栈视图.相反,如果您希望所有标签具有相同的宽度,则必须自己在标签之间创建宽度约束.例如,在添加每个新标签后,执行以下操作:
Note that you do not want the vertical lines to be the same width as the labels, so you must not set the distribution
property of the stack view to fillEqually
. Instead, if you want all the labels to have equal width, you must create width constraints between the labels yourself. For example, after adding each new label, do this:
if let firstLabel = stackView.arrangedSubviews.first as? UILabel {
label.widthAnchor.constraint(equalTo: firstLabel.widthAnchor).isActive = true
}
结果:
完整的操场代码(由 Federico Zanetello 更新到 Swift 4.1):
Full playground code (updated to Swift 4.1 by Federico Zanetello):
import UIKit
import PlaygroundSupport
extension UIFont {
var withSmallCaps: UIFont {
let feature: [UIFontDescriptor.FeatureKey: Any] = [
UIFontDescriptor.FeatureKey.featureIdentifier: kLowerCaseType,
UIFontDescriptor.FeatureKey.typeIdentifier: kLowerCaseSmallCapsSelector]
let attributes: [UIFontDescriptor.AttributeName: Any] = [UIFontDescriptor.AttributeName.featureSettings: [feature]]
let descriptor = self.fontDescriptor.addingAttributes(attributes)
return UIFont(descriptor: descriptor, size: pointSize)
}
}
let rootView = UIView(frame: CGRect(x: 0, y: 0, width: 320, height: 44))
rootView.backgroundColor = .white
PlaygroundPage.current.liveView = rootView
let stackView = UIStackView()
stackView.axis = .horizontal
stackView.alignment = .center
stackView.frame = rootView.bounds
rootView.addSubview(stackView)
typealias Item = (name: String, value: Int)
let items: [Item] = [
Item(name: "posts", value: 135),
Item(name: "followers", value: 6347),
Item(name: "following", value: 328),
]
let valueStyle: [NSAttributedStringKey: Any] = [NSAttributedStringKey.font: UIFont.boldSystemFont(ofSize: 12).withSmallCaps]
let nameStyle: [NSAttributedStringKey: Any] = [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 12).withSmallCaps,
NSAttributedStringKey.foregroundColor: UIColor.darkGray]
let valueFormatter = NumberFormatter()
valueFormatter.numberStyle = .decimal
for item in items {
if stackView.arrangedSubviews.count > 0 {
let separator = UIView()
separator.widthAnchor.constraint(equalToConstant: 1).isActive = true
separator.backgroundColor = .black
stackView.addArrangedSubview(separator)
separator.heightAnchor.constraint(equalTo: stackView.heightAnchor, multiplier: 0.4).isActive = true
}
let richText = NSMutableAttributedString()
let valueString = valueFormatter.string(for: item.value)!
richText.append(NSAttributedString(string: valueString, attributes: valueStyle))
richText.append(NSAttributedString(string: "
" + item.name, attributes: nameStyle))
let label = UILabel()
label.attributedText = richText
label.textAlignment = .center
label.numberOfLines = 0
stackView.addArrangedSubview(label)
if let firstLabel = stackView.arrangedSubviews.first as? UILabel {
label.widthAnchor.constraint(equalTo: firstLabel.widthAnchor).isActive = true
}
}
UIGraphicsBeginImageContextWithOptions(rootView.bounds.size, true, 1)
rootView.drawHierarchy(in: rootView.bounds, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
let png = UIImagePNGRepresentation(image)!
let path = NSTemporaryDirectory() + "/image.png"
Swift.print(path)
try! png.write(to: URL(fileURLWithPath: path))
这篇关于iOS - 在堆栈视图中以编程方式添加垂直线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!