我有UITableViewController
的自定义子类。它有一个包含许多行的部分。每行对应于相同的自定义表视图单元类。每个自定义单元格都有两个标签:myLabel1
& myLabel2
,这两个单元格的子视图contentView
。
每个myLabel1
都有一行文字,每个myLabel2
都有一行或两行文字,但每个单元格应该有相同的高度,就像每个myLabel2
有两行一样文本。
标签使用动态类型。
myLabel1.font = UIFont.preferredFont(forTextStyle: .headline)
myLabel2.font = UIFont.preferredFont(forTextStyle: .subheadline)
根据Working with Self-Sizing Table View Cells,我已使用自动布局定位每个标签,并且"将表格视图的rowHeight
属性设置为UITableViewAutomaticDimension
"这样行高就会随动态类型而变化。
如何让每个单元格具有相同的高度?
我应该如何估算表格视图的行高?
答案 0 :(得分:2)
UITableViewAutomaticDimension
将根据细胞内容大小估计细胞大小。我们必须计算单元格可能具有的最大高度,并为所有单元格返回此高度,而不是使用UITableViewAutomaticDimension
。
<强> CustomTableViewCell 强>
let kMargin: CGFloat = 8.0
class CustomTableViewCell: UITableViewCell {
@IBOutlet var singleLineLabel: UILabel!
@IBOutlet var doubleLineLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
updateFonts()
}
override func prepareForReuse() {
updateFonts()
}
func updateFonts() {
singleLineLabel.font = UIFont.preferredFont(forTextStyle:.title3)
doubleLineLabel.font = UIFont.preferredFont(forTextStyle:.body)
}
func updateCellForCellWidth(_ width:CGFloat) {
doubleLineLabel.preferredMaxLayoutWidth = width - (2*kMargin)
}
func fillCellWith(_ firstString: String, _ secondString: String) {
singleLineLabel.text = firstString
doubleLineLabel.text = secondString
}
}
设置虚拟单元格并列出动态类型的通知
var heightCalculatorDummyCell: CustomTableViewCell!
var maxHeight: CGFloat = 0.0
override func viewDidLoad() {
super.viewDidLoad()
heightCalculatorDummyCell = tableView.dequeueReusableCell(withIdentifier: "cell_id") as! CustomTableViewCell
maxHeight = getMaxHeight()
NotificationCenter.default.addObserver(self, selector: #selector(AutomaticHeightTableViewController.didChangePreferredContentSize), name: .UIContentSizeCategoryDidChange, object:nil)
}
使用虚拟单元格获取最大高度。
func getMaxHeight() -> CGFloat {
heightCalculatorDummyCell.updateFonts()
heightCalculatorDummyCell.fillCellWith("Title","A string that needs more than two lines. A string that needs more than two lines. A string that needs more than two lines. A string that needs more than two lines. A string that needs more than two lines.")
heightCalculatorDummyCell.updateCellForCellWidth(tableView.frame.size.width)
let size = heightCalculatorDummyCell.contentView.systemLayoutSizeFitting(UILayoutFittingCompressedSize)
return (size.height + 1)
}
处理表格视图重新加载通知
deinit {
NotificationCenter.default.removeObserver(self)
}
func didChangePreferredContentSize() {
maxHeight = getMaxHeight()
tableView.reloadData()
}
最后一步,在tableview委托中返回最高高度
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return titles.count
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return maxHeight
}
答案 1 :(得分:0)
将myLabel2
设为FixedHeightLabel
,使其高度始终为两行。
class FixedHeightLabel: TopAlignedLabel {
override var intrinsicContentSize: CGSize {
let oldText = text
text = "\n"
let height = sizeThatFits(CGSize(width: .max, height: .max)).height
text = oldText
return CGSize(width: UIViewNoIntrinsicMetric, height: height)
}
}
class TopAlignedLabel: UILabel {
override func drawText(in rect: CGRect) {
let textRect = super.textRect(forBounds: bounds, limitedToNumberOfLines: numberOfLines)
super.drawText(in: textRect)
}
}