在 UITableView 中对齐多个运行时生成的 UILabel
Aligning multiple runtime generated UILabels in a UITableView
我有一个 UITableView
需要通过类似
的列表样式来支持内容
但棘手的是"Label"的数量会随着每个单元格的不同而不同,有些可能只有4个,但也有多达12个。另外"Value"可以是单个单词或最多两行的短语(如上图所示)。所以我决定使用 UIStackView
来帮助我打包和调整我用来显示它的 UILabels
的大小。当 "Label" 的长度变化时,我目前遇到了一个问题,例如:
我需要 "Values" 的前端像第一张图片一样对齐,即使 "Label" 的长度不同。是否有 UIStackView
的行为允许这样做?或者是否有其他方法可以让我获得我需要的结果?
注意:每个 "Label" 和 "Value" 在一个 UIStackView
中,我这样做是为了对齐它们。
我也尝试过使用字符串格式,但是 "Values" 多行会在标签下换行,而不是像我在图片中设法做的那样自行换行。
我尝试将所有 "Labels" 放在一个 UIStackView
中,将所有 "Values" 放在另一个中,一旦 "Value"不止一行。
或者如果这可能是我在某个地方犯的错误,这就是我创建 UIStackViews
的方式:
var higherCount = 0
if labels.count<values.count {
higherCount = values.count
} else {
higherCount = labels.count
}
mainStackView = UIStackView(frame: CGRect(x: 0, y: 0, width: frame.width, height: frame.height))
for i in 0..<higherCount {
var height:CGFloat = 20
if (values[i] as NSString).size(attributes: [NSFontAttributeName:UIFont.systemFont(ofSize: UIFont.systemFontSize)]).width > frame.width {
height = 42
}
let stackViewToAdd = UIStackView(frame: CGRect(x: 0, y: 0, width: frame.width, height: height))
let label = UILabel(frame: CGRect(x: 0, y: 0, width: frame.width, height: height))
if labels.count<higherCount {
label.text = ""
} else {
label.text = labels[i]
}
label.setContentCompressionResistancePriority(1000, for: .horizontal)
label.setContentHuggingPriority(999, for: .horizontal)
stackViewToAdd.addArrangedSubview(label)
let value = UILabel(frame: CGRect(x: 0, y: 0, width: frame.width, height: height))
if values.count<higherCount {
value.text = ""
} else {
value.text = values[i]
}
value.lineBreakMode = .byWordWrapping
value.numberOfLines = 2
stackViewToAdd.addArrangedSubview(value)
mainStackView?.addArrangedSubview(stackViewToAdd)
}
mainStackView?.alignment = .fill
mainStackView?.axis = .vertical
mainStackView?.distribution = .fill
我以编程方式创建了单元格,然后您可以以编程方式调整单元格的大小,具体取决于 UILabel 内容的大小。
在我的例子中 Label
字体是 UIFont.systemFont(ofSize: 15)
,最小 TableViewCell 高度是 50,arrLabel1
和 arrLabel2
将是标签的内容。
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrLable1.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .default, reuseIdentifier: "\(indexPath.row)")
let lable1 = UILabel(frame: CGRect(x: 10, y: 10, width: view.frame.size.width - 20, height: 0))
lable1.numberOfLines = 0
lable1.font = UIFont.systemFont(ofSize: 15)
lable1.text = arrLable1[indexPath.row]
lable1.sizeToFit()
cell.addSubview(lable1)
let lable2 = UILabel(frame: CGRect(x: 10, y: lable1.frame.origin.y + lable1.frame.size.height + 10 , width: view.frame.size.width - 20, height: 0))
lable2.numberOfLines = 0
lable2.font = UIFont.systemFont(ofSize: 15)
lable2.text = arrLable2[indexPath.row]
lable2.sizeToFit()
cell.addSubview(lable2)
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath)
-> CGFloat {
let boundingRect1 = arrLable1[indexPath.row].boundingRect(with: CGSize(width: view.frame.size.width - 40 , height: CGFloat(MAXFLOAT)), options: NSStringDrawingOptions.usesLineFragmentOrigin,attributes:[ NSFontAttributeName : UIFont.systemFont(ofSize: 15)] ,context: nil)
let boundingRect2 = arrLable2[indexPath.row].boundingRect(with: CGSize(width: view.frame.size.width - 40 , height: CGFloat(MAXFLOAT)), options: NSStringDrawingOptions.usesLineFragmentOrigin,attributes:[ NSFontAttributeName : UIFont.systemFont(ofSize: 15)] ,context: nil)
guard boundingRect1.height + boundingRect2.height + 30 > 50 else {
return 50
}
return boundingRect1.height + boundingRect2.height + 30
}
Set Label
numberOfLines to 0
我有一个 UITableView
需要通过类似
但棘手的是"Label"的数量会随着每个单元格的不同而不同,有些可能只有4个,但也有多达12个。另外"Value"可以是单个单词或最多两行的短语(如上图所示)。所以我决定使用 UIStackView
来帮助我打包和调整我用来显示它的 UILabels
的大小。当 "Label" 的长度变化时,我目前遇到了一个问题,例如:
我需要 "Values" 的前端像第一张图片一样对齐,即使 "Label" 的长度不同。是否有 UIStackView
的行为允许这样做?或者是否有其他方法可以让我获得我需要的结果?
注意:每个 "Label" 和 "Value" 在一个 UIStackView
中,我这样做是为了对齐它们。
我也尝试过使用字符串格式,但是 "Values" 多行会在标签下换行,而不是像我在图片中设法做的那样自行换行。
我尝试将所有 "Labels" 放在一个 UIStackView
中,将所有 "Values" 放在另一个中,一旦 "Value"不止一行。
或者如果这可能是我在某个地方犯的错误,这就是我创建 UIStackViews
的方式:
var higherCount = 0
if labels.count<values.count {
higherCount = values.count
} else {
higherCount = labels.count
}
mainStackView = UIStackView(frame: CGRect(x: 0, y: 0, width: frame.width, height: frame.height))
for i in 0..<higherCount {
var height:CGFloat = 20
if (values[i] as NSString).size(attributes: [NSFontAttributeName:UIFont.systemFont(ofSize: UIFont.systemFontSize)]).width > frame.width {
height = 42
}
let stackViewToAdd = UIStackView(frame: CGRect(x: 0, y: 0, width: frame.width, height: height))
let label = UILabel(frame: CGRect(x: 0, y: 0, width: frame.width, height: height))
if labels.count<higherCount {
label.text = ""
} else {
label.text = labels[i]
}
label.setContentCompressionResistancePriority(1000, for: .horizontal)
label.setContentHuggingPriority(999, for: .horizontal)
stackViewToAdd.addArrangedSubview(label)
let value = UILabel(frame: CGRect(x: 0, y: 0, width: frame.width, height: height))
if values.count<higherCount {
value.text = ""
} else {
value.text = values[i]
}
value.lineBreakMode = .byWordWrapping
value.numberOfLines = 2
stackViewToAdd.addArrangedSubview(value)
mainStackView?.addArrangedSubview(stackViewToAdd)
}
mainStackView?.alignment = .fill
mainStackView?.axis = .vertical
mainStackView?.distribution = .fill
我以编程方式创建了单元格,然后您可以以编程方式调整单元格的大小,具体取决于 UILabel 内容的大小。
在我的例子中 Label
字体是 UIFont.systemFont(ofSize: 15)
,最小 TableViewCell 高度是 50,arrLabel1
和 arrLabel2
将是标签的内容。
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrLable1.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .default, reuseIdentifier: "\(indexPath.row)")
let lable1 = UILabel(frame: CGRect(x: 10, y: 10, width: view.frame.size.width - 20, height: 0))
lable1.numberOfLines = 0
lable1.font = UIFont.systemFont(ofSize: 15)
lable1.text = arrLable1[indexPath.row]
lable1.sizeToFit()
cell.addSubview(lable1)
let lable2 = UILabel(frame: CGRect(x: 10, y: lable1.frame.origin.y + lable1.frame.size.height + 10 , width: view.frame.size.width - 20, height: 0))
lable2.numberOfLines = 0
lable2.font = UIFont.systemFont(ofSize: 15)
lable2.text = arrLable2[indexPath.row]
lable2.sizeToFit()
cell.addSubview(lable2)
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath)
-> CGFloat {
let boundingRect1 = arrLable1[indexPath.row].boundingRect(with: CGSize(width: view.frame.size.width - 40 , height: CGFloat(MAXFLOAT)), options: NSStringDrawingOptions.usesLineFragmentOrigin,attributes:[ NSFontAttributeName : UIFont.systemFont(ofSize: 15)] ,context: nil)
let boundingRect2 = arrLable2[indexPath.row].boundingRect(with: CGSize(width: view.frame.size.width - 40 , height: CGFloat(MAXFLOAT)), options: NSStringDrawingOptions.usesLineFragmentOrigin,attributes:[ NSFontAttributeName : UIFont.systemFont(ofSize: 15)] ,context: nil)
guard boundingRect1.height + boundingRect2.height + 30 > 50 else {
return 50
}
return boundingRect1.height + boundingRect2.height + 30
}
Set
Label
numberOfLines to 0