Table 视图位于 table 视图的单元格内,但其框架高度为 0

Table view inside a cell of table view, however its frame height is 0

我在尝试在另一个 table 视图的单元格内构建 table 视图时遇到问题。我认为这是非常简单的任务...

应用程序结构:

我在 Reveal 应用程序中注意到 table 视图出现在单元格中并且它不会大喊约束不正确,一切似乎都很好。但是 table 视图的框架高度为 0.333。

显示应用程序屏幕截图和 table 视图存在的事实

但是用户会看到这个:

我尝试了一些方法(具有不同的值)作为艰难的:estimatedHeightForRowAtheightForRowAt,但是它们什么也没做,顺便说一句 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 视图单元格中标签的底部和顶部约束常数的总和。

我相信有更好的解决方案,但现在总比没有好。