UITableView 设置行高无效

UITableView setting row Height not having effect

为什么当我在 viewDidLoad() 中设置 tableView.rowHeight = 100 时,我总是得到默认的高度值 44.0?我也尝试设置 tableView.estimatedHeight =100 但没有成功,我也尝试设置委托方法 tableView.heightForRowAt 但这似乎也没有任何效果。所以问题是:如何设置tableView Cell的高度?

    override func viewDidLoad(){ // tableView viewDidLoad
    super.viewDidLoad()
    tableView.rowHeight = 100
    tableView.register(TickerCell.self, forCellReuseIdentifier: "Cell")
}
    // Custom Cell Init 
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)
    backgroundColor = .clear
    print(frame.height) // always prints 44.0
    let symbolstack = UIStackView(arrangedSubviews: [symbolLabel,companyLabel])
    let sectorstack = UIStackView(arrangedSubviews: [sectorLabel,exchangeLabel])
    let mainStack = UIStackView(arrangedSubviews: [symbolstack,sectorstack])
    sectorstack.axis = .vertical
    symbolstack.axis = .vertical
    sectorstack.alignment = .trailing
    symbolstack.alignment = .leading
    symbolstack.distribution = .fillEqually
    sectorstack.distribution = .fillEqually
    mainStack.distribution = .fillProportionally
    addSubview(mainStack)
    mainStack.translatesAutoresizingMaskIntoConstraints = false
    mainStack.heightAnchor.constraint(equalTo: self.heightAnchor).isActive = true
    mainStack.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -45).isActive = true
    mainStack.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 15).isActive = true
    addSubview(WatchlistStar)
    WatchlistStar.translatesAutoresizingMaskIntoConstraints = false
    WatchlistStar.widthAnchor.constraint(equalToConstant: 15).isActive = true
    WatchlistStar.leadingAnchor.constraint(equalTo: mainStack.trailingAnchor, constant: 20).isActive = true
    WatchlistStar.heightAnchor.constraint(equalToConstant: 15).isActive = true
    WatchlistStar.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
}

所以问题似乎出在单元格初始化方法中,我在 viewDidLoad 中设置的 rowHeight 似乎没有注册,只有在 prepareForReuse 中打印 frame.height 时我才得到打印了100个,那我用什么方法设置单元格布局呢?

一个单元格不是天生就知道它的高度的,所以 init 是查看框架的毫无意义的地方。事实上,它没有固有的高度。细胞被重复使用。它们的高度仅与 table 中当前正在使用的特定行有关。当单元格用于不同的行时,该高度可能会发生变化(因为行的高度可能不同)。所以您的布局需要应对这一点。

在您显示的代码中,您使用的是自动版式。自动布局的全部要点是您在任何时候都不关心事物的框架。随着周围框架的变化,一切都会自动调整。自动版式是关于关系

所以这种情况下的解决办法是:不要frame.height。你不需要知道它。只要布局视图和单元格之间的关系,当单元格出现时一切都会正确,如果你正确使用了自动布局。

另一方面,正如您现在在评论中所说“我被迫 [使用自动布局] 不是因为我想这样做”— 好吧,如果目标是手动布局,就像我们之前所做的那样autolayout,那么做的地方就是数据源的cellForRowAt:。或者,如果您希望单元格自行布局,您 可以 尝试在单元格的 layoutSubviews 中执行此操作。请参阅我的旧版在线书籍,了解我们过去是如何做到这一点的:http://www.apeth.com/iOSBook/ch21.html#_custom_cells

要非常小心区分添加子视图和调整它们的大小。您不想错误地添加您已经添加的子视图。所以在 init 中添加子视图,当然,因为它只被调用一次,但是在行的实际大小已经传达给单元格的地方调整它们的大小。

再提一个建议。您当前的代码使用短语 addSubview,意思是 self.addSubview。那是完全错误和非法的。永远不要将子视图直接添加到单元格。仅将它添加到单元格的 contentView,并根据它调整大小。

override func viewDidLoad() {
    super.viewDidLoad()
    self.tableView.rowHeight = UITableView.automaticDimension;
    self.tableView.estimatedRowHeight = 40 
}