Table 视图位于 table 视图的单元格内,但其框架高度为 0
Table view inside a cell of table view, however its frame height is 0
我在尝试在另一个 table 视图的单元格内构建 table 视图时遇到问题。我认为这是非常简单的任务...
应用程序结构:
- Collection 查看锻炼项目。
- 点击每个按钮后,用户将移至静态 table 视图,这是出现问题的地方。
我在 Reveal 应用程序中注意到 table 视图出现在单元格中并且它不会大喊约束不正确,一切似乎都很好。但是 table 视图的框架高度为 0.333。
显示应用程序屏幕截图和 table 视图存在的事实
但是用户会看到这个:
我尝试了一些方法(具有不同的值)作为艰难的:estimatedHeightForRowAt
、heightForRowAt
,但是它们什么也没做,顺便说一句 UITableView.automaticDimension
returns -1。
但是,当我为最外层 table 视图的行显式设置高度时,一切都很好,除了不同元素的大小会有所不同,并且 table 视图太大或太小。我做了这个约束,但它似乎只适用于元素有 3 个拆分的情况:
self.heightAnchor.constraint(equalToConstant: 40 + titleLabel.frame.height + CGFloat(splits.count) * 44.0)
With 3 splits in element
Less than 3
我读到将自定义单元格的子视图而不是单元格本身添加到 contentView 对某些人有所帮助,但就我而言,我收到了这条消息:
Warning once only: Detected a case where constraints ambiguously suggest a height of zero for a table view cell's content view. We're considering the collapse unintentional and using standard height instead. Cell: <projectClimber.SplitCell: 0x140670050; baseClass = UITableViewCell; frame = (0 0; 355 44); autoresize = W; layer = <CALayer: 0x600003797700>>
我实际上能够通过删除 contentView 并将子视图添加到单元格本身来处理此警告。但这并没有解决任何问题。
我真的不知道如何为 table 视图的高度设置适当的值,也许有一种不使用 table 视图的方法,或者可能有不同的方法。我想听听您对此的看法,谢谢。
代码
主要table视图
class WorkoutStatisticsTableViewController: UITableViewController {
....
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//...
//Switch statement and other cases
//...
case 3:
let cell = FourthTableViewCell()
cell.configure(with: workout)
cell.selectionStyle = .none
// Here I added
return cell
}
//I tried these methods, but nothing changed
// override func tableView(_ tableView: UITableView, estimatedHeightForRowAt
indexPath: IndexPath) -> CGFloat {
// return 250
// }
//
// override func tableView(_ tableView: UITableView, heightForRowAt indexPath:
IndexPath) -> CGFloat {
//
// return UITableView.automaticDimension
// }
....
}
Table 视图单元格 class,其中放置标题标签和 table 视图
class FourthTableViewCell: UITableViewCell, UITableViewDelegate, UITableViewDataSource {
//...
//Methods for tableview delegate and data source and implementation of title label
//...
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) ->
UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: SplitCell.reuseIdentifier, for: indexPath) as! SplitCell
cell.configure(cellWithNumber: indexPath.row + 1, with: splits[indexPath.row])
cell.selectionStyle = .none
return cell
}
//Number of splits, i.e. rows in table view in this cell
var splits: [Int] = []
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
self.tableView.dataSource = self
self.tableView.delegate = self
//just for making table view visible
self.tableView.backgroundColor = .orange
tableView.register(SplitCell.self, forCellReuseIdentifier: SplitCell.reuseIdentifier)
addSubview(titleLabel)
addSubview(tableView)
titleLabel.translatesAutoresizingMaskIntoConstraints = false
tableView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
titleLabel.topAnchor.constraint(equalTo: topAnchor, constant: 20),
titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20),
titleLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -20),
tableView.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 10),
tableView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 10),
tableView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -10),
tableView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -10),
// Tried this line for calculating height of cell
// self.heightAnchor.constraint(equalToConstant: 40 + titleLabel.frame.height + CGFloat(splits.count) * 44.0)
])
}
//Configure cell with workout element, which is used for taking splits
func configure(with workout: Workout) {
print("Configure func, workout's splits \(workout.splits.count)")
//Need to populate splits this way, because in workout I use List<Int>
for item in workout.splits {
self.splits.append(item)
}
}
}
拆分单元格class。哪里只有两个标签
class SplitCell: UITableViewCell {
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
addSubview(titleLabel)
addSubview(timeLabel)
titleLabel.translatesAutoresizingMaskIntoConstraints = false
timeLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
titleLabel.topAnchor.constraint(equalTo: topAnchor, constant: 10),
titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 15),
titleLabel.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -10),
timeLabel.topAnchor.constraint(equalTo: topAnchor, constant: 10),
timeLabel.leadingAnchor.constraint(equalTo: titleLabel.trailingAnchor, constant: 50),
timeLabel.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -10)
])
}
func configure(cellWithNumber number: Int, with time: Int) {
titleLabel.text = "Split #\(number)"
timeLabel.text = String.makeTimeString(seconds: time)
}
}
经过多次尝试,我决定将此约束用于 table 视图,它位于静态 table 视图的单元格内:
tableView.heightAnchor.constraint(equalToConstant: CGFloat(splits.count) * 27)
但是还有一个问题——魔法值。 27 是 17 的和,它是标签的高度,10 是内部 table 视图单元格中标签的底部和顶部约束常数的总和。
我相信有更好的解决方案,但现在总比没有好。
我在尝试在另一个 table 视图的单元格内构建 table 视图时遇到问题。我认为这是非常简单的任务...
应用程序结构:
- Collection 查看锻炼项目。
- 点击每个按钮后,用户将移至静态 table 视图,这是出现问题的地方。
我在 Reveal 应用程序中注意到 table 视图出现在单元格中并且它不会大喊约束不正确,一切似乎都很好。但是 table 视图的框架高度为 0.333。
显示应用程序屏幕截图和 table 视图存在的事实
但是用户会看到这个:
我尝试了一些方法(具有不同的值)作为艰难的:estimatedHeightForRowAt
、heightForRowAt
,但是它们什么也没做,顺便说一句 UITableView.automaticDimension
returns -1。
但是,当我为最外层 table 视图的行显式设置高度时,一切都很好,除了不同元素的大小会有所不同,并且 table 视图太大或太小。我做了这个约束,但它似乎只适用于元素有 3 个拆分的情况:
self.heightAnchor.constraint(equalToConstant: 40 + titleLabel.frame.height + CGFloat(splits.count) * 44.0)
With 3 splits in element | Less than 3 |
---|---|
我读到将自定义单元格的子视图而不是单元格本身添加到 contentView 对某些人有所帮助,但就我而言,我收到了这条消息:
Warning once only: Detected a case where constraints ambiguously suggest a height of zero for a table view cell's content view. We're considering the collapse unintentional and using standard height instead. Cell: <projectClimber.SplitCell: 0x140670050; baseClass = UITableViewCell; frame = (0 0; 355 44); autoresize = W; layer = <CALayer: 0x600003797700>>
我实际上能够通过删除 contentView 并将子视图添加到单元格本身来处理此警告。但这并没有解决任何问题。
我真的不知道如何为 table 视图的高度设置适当的值,也许有一种不使用 table 视图的方法,或者可能有不同的方法。我想听听您对此的看法,谢谢。
代码
主要table视图
class WorkoutStatisticsTableViewController: UITableViewController {
....
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//...
//Switch statement and other cases
//...
case 3:
let cell = FourthTableViewCell()
cell.configure(with: workout)
cell.selectionStyle = .none
// Here I added
return cell
}
//I tried these methods, but nothing changed
// override func tableView(_ tableView: UITableView, estimatedHeightForRowAt
indexPath: IndexPath) -> CGFloat {
// return 250
// }
//
// override func tableView(_ tableView: UITableView, heightForRowAt indexPath:
IndexPath) -> CGFloat {
//
// return UITableView.automaticDimension
// }
....
}
Table 视图单元格 class,其中放置标题标签和 table 视图
class FourthTableViewCell: UITableViewCell, UITableViewDelegate, UITableViewDataSource {
//...
//Methods for tableview delegate and data source and implementation of title label
//...
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) ->
UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: SplitCell.reuseIdentifier, for: indexPath) as! SplitCell
cell.configure(cellWithNumber: indexPath.row + 1, with: splits[indexPath.row])
cell.selectionStyle = .none
return cell
}
//Number of splits, i.e. rows in table view in this cell
var splits: [Int] = []
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
self.tableView.dataSource = self
self.tableView.delegate = self
//just for making table view visible
self.tableView.backgroundColor = .orange
tableView.register(SplitCell.self, forCellReuseIdentifier: SplitCell.reuseIdentifier)
addSubview(titleLabel)
addSubview(tableView)
titleLabel.translatesAutoresizingMaskIntoConstraints = false
tableView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
titleLabel.topAnchor.constraint(equalTo: topAnchor, constant: 20),
titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20),
titleLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -20),
tableView.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 10),
tableView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 10),
tableView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -10),
tableView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -10),
// Tried this line for calculating height of cell
// self.heightAnchor.constraint(equalToConstant: 40 + titleLabel.frame.height + CGFloat(splits.count) * 44.0)
])
}
//Configure cell with workout element, which is used for taking splits
func configure(with workout: Workout) {
print("Configure func, workout's splits \(workout.splits.count)")
//Need to populate splits this way, because in workout I use List<Int>
for item in workout.splits {
self.splits.append(item)
}
}
}
拆分单元格class。哪里只有两个标签
class SplitCell: UITableViewCell {
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
addSubview(titleLabel)
addSubview(timeLabel)
titleLabel.translatesAutoresizingMaskIntoConstraints = false
timeLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
titleLabel.topAnchor.constraint(equalTo: topAnchor, constant: 10),
titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 15),
titleLabel.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -10),
timeLabel.topAnchor.constraint(equalTo: topAnchor, constant: 10),
timeLabel.leadingAnchor.constraint(equalTo: titleLabel.trailingAnchor, constant: 50),
timeLabel.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -10)
])
}
func configure(cellWithNumber number: Int, with time: Int) {
titleLabel.text = "Split #\(number)"
timeLabel.text = String.makeTimeString(seconds: time)
}
}
经过多次尝试,我决定将此约束用于 table 视图,它位于静态 table 视图的单元格内:
tableView.heightAnchor.constraint(equalToConstant: CGFloat(splits.count) * 27)
但是还有一个问题——魔法值。 27 是 17 的和,它是标签的高度,10 是内部 table 视图单元格中标签的底部和顶部约束常数的总和。
我相信有更好的解决方案,但现在总比没有好。