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
}
为什么当我在 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
}