iOS/Swift:嵌入UITableView的动态UITableView单元格行高不工作
我有一个iOS/Swift:嵌入UITableView的动态UITableView单元格行高不工作,ios,swift,uitableview,autolayout,constraints,Ios,Swift,Uitableview,Autolayout,Constraints,我有一个UITableView单元格,它在顶部包含一个UICollectionView,在底部包含一个UITableView。其思想是在内部UITableView中创建动态数量的单元格,并且包含两个子视图的父级UITableViewCell将按比例增加其高度 我试图利用UITableViewCell的estimatedRowHeight+uitableViewAutomaticDeption功能,该功能将允许单元格高度动态增加。然而,它不起作用。它将从视图中完全删除嵌入的UITableView
UITableView单元格
,它在顶部包含一个UICollectionView
,在底部包含一个UITableView
。其思想是在内部UITableView
中创建动态数量的单元格,并且包含两个子视图的父级UITableViewCell
将按比例增加其高度
我试图利用UITableViewCell
的estimatedRowHeight
+uitableViewAutomaticDeption
功能,该功能将允许单元格高度动态增加。然而,它不起作用。它将从视图中完全删除嵌入的UITableView
我没有做任何限制附带的UITableView
高度的限制,因此我不确定它为什么不起作用
以下是尝试创建动态大小的UITableViewCell
的实现:
class OverviewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = "Enclosed Table View Example"
}
func numberOfSections(in tableView: UITableView) -> Int {
return 3
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 325 // Height for inner table view with 1 cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 45
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let cell = tableView.dequeueReusableCell(withIdentifier: "appHeaderCell") as! AppHeaderCell
return cell
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "appCell", for: indexPath) as! AppCell
return cell
}
}
我唯一的猜测是,约束bottom=internaltable View.bottom+7
导致了问题,但当删除此约束时,整个视图都会崩溃
如何使复杂的外部
UITableView单元格
根据嵌入的UITableView
中的单元格数量动态调整高度?尽管这似乎是个好主意,将UITableViewAutomaticDimension
与EstimatedRowheaight
结合使用,不适合在表视图单元格中包含常规内容的情况下使用。使用heightForRowAt
方法,可以在每个单元格位于表格中心之前计算其大小
一旦我们知道内部表中有多少个单元格,就需要创建一个数组,其元素对应于最终确定外部单元格高度的内部单元格数量,因为所有其他内容都是常量
let cellListFromData: [CGFloat] = [3, 1, 4]
此数组将提供外部表视图中的节数:
func numberOfSections(in tableView: UITableView) -> Int {
return cellListFromData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "appCell", for: indexPath) as! AppCell
cell.numberOfCells = Int(cellListFromData[indexPath.section])
cell.innerTableView.reloadData()
return cell
}
我们将按以下方式将此数组中的每个元素转换为单元格高度:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let prototypeCell = tableView.dequeueReusableCell(withIdentifier: "appCell") as! AppCell
let baseHeight = betweenCellSpacing + prototypeCell.innerCollectionView.contentSize.height + prototypeCell.innerTableView.sectionHeaderHeight + outerTableView.sectionHeaderHeight
let dynamicHeight = prototypeCell.innerTableView.contentSize.height - prototypeCell.innerTableView.sectionHeaderHeight
return baseHeight + (dynamicHeight * cellListFromData[indexPath.section])
}
也就是说,在heightForRowAt
方法中,我们将一个不会在结果视图中使用的原型单元出列(在这种情况下,dequeueReusableCell
在cellForRowAt
中不被调用)。我们使用这个原型单元来提取关于单元内容的常量和动态信息。baseHeight
是单元格中所有常量元素的累计高度(加上单元格之间的间距),dynamicHeight
是内部UITableViewCell
的高度。然后每个单元格的高度变为baseHeight+dynamicHeight*cellListFromData[indexPath.section]
接下来,我们为自定义单元格的类添加一个numberOfCells
变量,并在主表视图中的cellForRowAt
方法中进行设置:
func numberOfSections(in tableView: UITableView) -> Int {
return cellListFromData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "appCell", for: indexPath) as! AppCell
cell.numberOfCells = Int(cellListFromData[indexPath.section])
cell.innerTableView.reloadData()
return cell
}
numberOfCells
使用与我们用于获取单元格高度的相同的cellListFromData
设置。此外,在设置内部表视图的单元格数后,在该视图上调用reloadData()
,以便在UI中看到该更新,这一点非常重要
以下是完整的代码:
class OverviewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet weak var outerTableView: UITableView!
let cellSpacing: CGFloat = 25
let data: [CGFloat] = [3, 1, 4]
override func viewDidLoad() {
super.viewDidLoad()
}
func numberOfSections(in tableView: UITableView) -> Int {
return data.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let prototypeCell = tableView.dequeueReusableCell(withIdentifier: "appCell") as! AppCell
let baseHeight = cellSpacing + prototypeCell.innerCollectionView.contentSize.height + prototypeCell.innerTableView.sectionHeaderHeight + outerTableView.sectionHeaderHeight
let dynamicHeight = prototypeCell.innerTableView.contentSize.height - prototypeCell.innerTableView.sectionHeaderHeight
return baseHeight + (dynamicHeight * data[indexPath.section])
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "appCell", for: indexPath) as! AppCell
cell.numberOfCells = Int(data[indexPath.section])
cell.innerTableView.reloadData()
return cell
}
}
class AppCell: UITableViewCell, UITableViewDataSource, UITableViewDelegate {
@IBOutlet weak var innerCollectionView: UICollectionView!
@IBOutlet weak var innerTableView: UITableView!
var numberOfCells: Int = 0
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return numberOfCells
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let cell = tableView.dequeueReusableCell(withIdentifier: "featureHeaderCell") as! BuildHeaderCell
return cell
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "innerCell", for: indexPath) as! InnerCell
return cell
}
}
此处不包括与配置内部集合视图相关的方法,因为它与问题无关