自动调整 UITableViewCell 时 UILabel 高度不明确
Ambiguous UILabel height in autoresizing UITableViewCell
我很难实现具有自动调整单元格大小的 UITableView。我正在尝试在具有自动大小的单元格内使用带有 2 个标签的 UIStackView。
整体看起来不错,但我遇到了以下运行时问题:
我觉得我的约束应该足以满足这里的用例,但我想消除这里的歧义。
如何实现?这里通常采用什么方法?
我准备了一个示例项目,它简化了我的用例,但仍然演示了这个问题。这是我的控制器:
class ViewController: UIViewController {
struct CellData {
let title: String
let subtitle: String
}
let table = UITableView()
let data = [
CellData(title: "Foo", subtitle: "Bar"),
CellData(title: "Baz", subtitle: "FooBar")
]
private let cellReuseID = "CellReuseID"
override func viewDidLoad() {
super.viewDidLoad()
table.register(Cell.self, forCellReuseIdentifier: cellReuseID)
table.dataSource = self
table.rowHeight = UITableView.automaticDimension
table.tableFooterView = UIView(frame: .zero)
table.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(table)
NSLayoutConstraint.activate([
table.leadingAnchor.constraint(equalTo: view.leadingAnchor),
table.trailingAnchor.constraint(equalTo: view.trailingAnchor),
table.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
table.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
])
}
}
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
data.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseID) as? Cell else {
fatalError()
}
cell.title = data[indexPath.row].title
cell.subtitle = data[indexPath.row].subtitle
return cell
}
}
它使用的单元格:
class Cell: UITableViewCell {
var title: String? {
didSet {
titleLabel.text = title
}
}
var subtitle: String? {
didSet {
subtitleLabel.text = subtitle
}
}
let titleLabel = UILabel()
let subtitleLabel = UILabel()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupView()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupView() {
let stackView = UIStackView()
stackView.axis = .vertical
stackView.alignment = .top
stackView.distribution = .fill
stackView.spacing = 8
stackView.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(stackView)
NSLayoutConstraint.activate([
stackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
stackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
stackView.topAnchor.constraint(equalTo: contentView.topAnchor)
])
stackView.addArrangedSubview(titleLabel)
stackView.addArrangedSubview(subtitleLabel)
}
}
高度不明确的原因是因为两个标签具有相同的内容拥抱优先级。
自动布局做出“最佳猜测”并且您获得了所需的输出——但您仍然会在调试视图层次结构中看到问题。
要摆脱它,您可以给一个标签更高的拥抱优先级。
例如(在setupView()
):
titleLabel.setContentHuggingPriority(.defaultHigh + 1, for: .vertical)
subtitleLabel.setContentHuggingPriority(.defaultHigh, for: .vertical)
我很难实现具有自动调整单元格大小的 UITableView。我正在尝试在具有自动大小的单元格内使用带有 2 个标签的 UIStackView。
整体看起来不错,但我遇到了以下运行时问题:
我觉得我的约束应该足以满足这里的用例,但我想消除这里的歧义。
如何实现?这里通常采用什么方法?
我准备了一个示例项目,它简化了我的用例,但仍然演示了这个问题。这是我的控制器:
class ViewController: UIViewController {
struct CellData {
let title: String
let subtitle: String
}
let table = UITableView()
let data = [
CellData(title: "Foo", subtitle: "Bar"),
CellData(title: "Baz", subtitle: "FooBar")
]
private let cellReuseID = "CellReuseID"
override func viewDidLoad() {
super.viewDidLoad()
table.register(Cell.self, forCellReuseIdentifier: cellReuseID)
table.dataSource = self
table.rowHeight = UITableView.automaticDimension
table.tableFooterView = UIView(frame: .zero)
table.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(table)
NSLayoutConstraint.activate([
table.leadingAnchor.constraint(equalTo: view.leadingAnchor),
table.trailingAnchor.constraint(equalTo: view.trailingAnchor),
table.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
table.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
])
}
}
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
data.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseID) as? Cell else {
fatalError()
}
cell.title = data[indexPath.row].title
cell.subtitle = data[indexPath.row].subtitle
return cell
}
}
它使用的单元格:
class Cell: UITableViewCell {
var title: String? {
didSet {
titleLabel.text = title
}
}
var subtitle: String? {
didSet {
subtitleLabel.text = subtitle
}
}
let titleLabel = UILabel()
let subtitleLabel = UILabel()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setupView()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupView() {
let stackView = UIStackView()
stackView.axis = .vertical
stackView.alignment = .top
stackView.distribution = .fill
stackView.spacing = 8
stackView.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(stackView)
NSLayoutConstraint.activate([
stackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
stackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
stackView.topAnchor.constraint(equalTo: contentView.topAnchor)
])
stackView.addArrangedSubview(titleLabel)
stackView.addArrangedSubview(subtitleLabel)
}
}
高度不明确的原因是因为两个标签具有相同的内容拥抱优先级。
自动布局做出“最佳猜测”并且您获得了所需的输出——但您仍然会在调试视图层次结构中看到问题。
要摆脱它,您可以给一个标签更高的拥抱优先级。
例如(在setupView()
):
titleLabel.setContentHuggingPriority(.defaultHigh + 1, for: .vertical)
subtitleLabel.setContentHuggingPriority(.defaultHigh, for: .vertical)