Swe*_*per 0 uitableview autolayout swift
我已经阅读了很多关于如何根据单元格中的文本自动调整表格单元格高度的内容。从这个,这个和这个,似乎UITableView.automaticDimension是要走的路。显然它也适用于系统(即非自定义)单元。
在我的表格视图中,我使用了一堆样式为“Right Detail”的系统单元格(请注意,这不是我的自定义单元格):
我让两个标签的“行”为 0,“换行”为“换行”以启用自动换行。现在在我的表 VC 中,我用一些数据填充了表视图,这些数据旨在显示我遇到的问题:
var strings = [("Some Very Long Black Text That Doesn't Fit. Foo Bar Baz.", ""),
("A", "Short Text"),
("B", "Foo Bar"),
("Not working:", "Some Very Long Grey Text That Doesn't Fit. Foo Bar Baz"),
("C", "Another Text")]
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return strings.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell")
cell?.textLabel?.text = strings[indexPath.row].0
cell?.detailTextLabel?.text = strings[indexPath.row].1
return cell!
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
Run Code Online (Sandbox Code Playgroud)
这是结果:
如您所见,第一行正确调整了其高度以适合标签,但第四行的标签超出了其单元格。似乎表格视图只尝试将行高调整为textLabel.text,而detailTextLabel根本不考虑文本。
在计算单元格高度时,如何让表格视图同时考虑两个标签的文本?
额外的尝试:
我想我可以创建一个与系统“Right Detail”单元格样式非常相似的自定义单元格并使用该单元格代替。无论我做什么,我都无法重新创建系统单元的约束。例如,这是我最好的尝试。
让它完全按照你的意愿工作是很困难的。
自动布局进行多次“传递”以尝试满足布局要求。但是,想想它必须做什么:
并且,在该过程中的哪一点可以确定两个标签都将结束包装,因此使每个标签的宽度为 50%?请记住,单元格宽度会因设备和方向而异?
您可能想要查看您希望显示的实际数据,并考虑它的实际外观。“正确的细节单元”设计最终可能不会成为最佳布局。
也就是说 - 这是一个可能适合您的自定义单元格。它需要大量的边缘测试来查看是否有任何尺寸被丢弃(例如,由于很长的字符串和/或字符串长度之间的差异很大):
class MyRightDetailCell: UITableViewCell {
var myTextLabel: UILabel = {
let v = UILabel()
v.translatesAutoresizingMaskIntoConstraints = false
v.numberOfLines = 0
v.textAlignment = .left
v.font = UIFont.systemFont(ofSize: 17.0)
v.textColor = .black
v.setContentHuggingPriority(.required, for: .horizontal)
v.setContentHuggingPriority(.required, for: .vertical)
v.setContentCompressionResistancePriority(.required, for: .horizontal)
v.setContentCompressionResistancePriority(.required, for: .vertical)
return v
}()
var myDetailTextLabel: UILabel = {
let v = UILabel()
v.translatesAutoresizingMaskIntoConstraints = false
v.numberOfLines = 0
v.textAlignment = .right
v.font = UIFont.systemFont(ofSize: 17.0)
v.textColor = .darkGray
v.setContentHuggingPriority(.required, for: .horizontal)
v.setContentHuggingPriority(.required, for: .vertical)
v.setContentCompressionResistancePriority(.required, for: .horizontal)
v.setContentCompressionResistancePriority(.required, for: .vertical)
return v
}()
var theStackView: UIStackView = {
let v = UIStackView()
v.translatesAutoresizingMaskIntoConstraints = false
v.axis = .horizontal
v.alignment = .top
v.distribution = .fill
v.spacing = 8
v.setContentHuggingPriority(.required, for: .vertical)
v.setContentCompressionResistancePriority(.required, for: .vertical)
return v
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func commonInit() -> Void {
contentView.addSubview(theStackView)
theStackView.addArrangedSubview(myTextLabel)
theStackView.addArrangedSubview(myDetailTextLabel)
let g = contentView.layoutMarginsGuide
NSLayoutConstraint.activate([
theStackView.topAnchor.constraint(equalTo: g.topAnchor, constant: 0.0),
theStackView.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: 0.0),
theStackView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 0.0),
theStackView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: 0.0),
])
}
}
class RightDetailTableViewController: UITableViewController {
var strings = [
("Some Very Long Black Text That Doesn't Fit. Foo Bar Baz.", ""),
("A", "Short Text"),
("B Somewhat Much Longer Left Label Text.", "With long right label text."),
("Working Now?", "Some Very Long Grey Text (Three Lines?) That Doesn't Fit. Foo Bar Baz"),
("C", "Another Text"),
("D", "With Long Right Label Text That Will Need To Wrap."),
]
let cellID = "MYRDC"
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(MyRightDetailCell.self, forCellReuseIdentifier: cellID)
// make 5 copies of the test data so we'll have plenty of rows
// for scrolling (to check cell re-use)
for _ in 1...5 {
strings.append(contentsOf: strings)
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// due to the complexity of the cell, the layout is more reliable if the
// table is reloaded here - try it with and without this extra reloadData() call
tableView.reloadData()
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return strings.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellID, for: indexPath) as! MyRightDetailCell
cell.myTextLabel.text = strings[indexPath.row].0
cell.myDetailTextLabel.text = strings[indexPath.row].1
// if either label has no text (""), set it to hidden
// to remove the stack view's spacing
cell.myTextLabel.isHidden = (strings[indexPath.row].0 == "")
cell.myDetailTextLabel.isHidden = (strings[indexPath.row].1 == "")
// un-comment the next two lines to show label background colors
// to make it easy to see the label frames
//cell.myTextLabel.backgroundColor = .cyan
//cell.myDetailTextLabel.backgroundColor = .green
return cell
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
| 归档时间: |
|
| 查看次数: |
133 次 |
| 最近记录: |