我正在尝试以编程方式在堆栈视图内的标签之间添加垂直线.
所需的完成将是这样的图像:
我可以添加标签,所有标签都有所需的间距;我可以添加水平线,但我无法弄清楚如何在中间添加这些分隔符垂直线.
我想这样做:
let stackView = UIStackView(arrangedSubviews: [label1,verticalLine,label2,label3])
任何提示?
谢谢
解决方法
您不能在两个地方使用相同的视图,因此您需要创建两个单独的垂直线视图.您需要像这样配置每个垂直线视图:
>设置背景颜色.
>将宽度限制为1(因此您得到一条线,而不是一个矩形).
>限制其高度(因此它不会被拉伸到堆栈视图的整个高度).
因此,一次一个地添加标签到堆栈视图,并在将每个标签添加到堆栈视图之前执行类似的操作:
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 }
请注意,您不希望垂直线与标签的宽度相同,因此您不能将堆栈视图的分布属性设置为fillEqually.相反,如果您希望所有标签具有相等的宽度,则必须自己在标签之间创建宽度约束.例如,在添加每个新标签后,执行以下操作:
if let firstLabel = stackView.arrangedSubviews.first as? UILabel { label.widthAnchor.constraint(equalTo: firstLabel.widthAnchor).isActive = true }
结果:
完整的游乐场代码(由Federico Zanetello更新为Swift 4.1):
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: "\n" + 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))