我有以下布局
我正在尝试使UICollectionView始终显示3个项目,无论屏幕大小。我能够根据屏幕宽度显示项目,并能够设置高度。但是,表视图的高度不会从CategoryCell内部更改。这是代码:
// CategoryCell.swift
func awakeFromNib() {
super.awakeFromNib()
// Calculate width and height based on screen width
let screenWidth = UIScreen.main.bounds.width
let itemWidth = screenWidth / 3.0
let itemHeight = itemWidth / 0.75 // 3:4 aspect ratio
// Change height of table view cell
self.bounds.size.height = self.bounds.size.height - collectionView.bounds.size.height + itemHeight
// This is the line does nothing
// It should remove collectionView height from tableView (height of collectionView is set through autolayout) then add he new height to it.
// Set collection view height to equal to item height
collectionView.bounds.size.height = itemHeight
// set item height
let layout = collectionViewProducts.collectionViewLayout as! UICollectionViewFlowLayout
layout.itemSize = CGSize(width: itemWidth, height: itemHeight - 1.0)
// -1.0 because item/cell height needs to be SMALLER than collection view height
}
如何从单元格类本身内部更改表格视图单元格高度?我唯一的猜测是我不应该在awakeFromNib中执行这些操作,但是我无法找到另外的函数来调用它们。
编辑:我正在使用RxSwift,所以我的数据源代码如下:
let observable = Observable.just(data)
observable.bindTo(tableView.rx.items(cellIdentifier: "CategoryCell", cellType: CategoryCell.self)) { (row, element, cell) in
cell.setCategory(category: element)
}.disposed(by: disposeBag)
tableView.rx.setDelegate(self).disposed(by: disposeBag)
答案 0 :(得分:1)
您可以实现UITableViewDelegate
的{{1}}并根据变量返回值。您可以在heightForRowAt
UICollectionView
计算的任何位置设置变量。因此,当您完成计算后,您应该能够执行表视图数据重新加载,并且布局应使用新的itemHeight
值进行更新。
我没有测试过代码,但上面的代码应该可行。如果您遇到任何问题,或者我以某种方式误解了您的要求,请告诉我。
答案 1 :(得分:0)
您需要为每个单元格提供tableview的单元格高度,并根据该高度计算您的collectionview单元格的高度。对于tableview的单元格的动态高度,您需要实现这些方法。
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
或者如果你需要固定的高度,那么只需使用这些方法,并根据你的计算提供你的细胞高度。
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return fixedSize //e.g 100
}
试着希望它会对你有所帮助。
答案 2 :(得分:0)
谢谢@Prince和@Fahim。你的答案给了我一个想法,将我的行高逻辑移动到tableView委托。因为,我正在根据屏幕宽度和宽高比计算高度。我只是将相同的逻辑移动到tableView高度:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let screenWidth = UIScreen.main.bounds.size.width
// 3 items + 10px gap between cells
let itemWidth = (screenWidth / 3.0) - 20
// 3:4 aspect ratio + other elements
let itemHeight = (itemWidth) / 0.75 + 110
return itemHeight
}
现在这个解决方案对我来说正常,我想改变它,所以它考虑了单元本身。
我知道在答案中提出一个问题很奇怪,但它与这个帖子有关,所以我认为最好在这里问一下。如何从indexPath获取单元对象?使用tableView.cellForRow(at: indexPath)
会让我无法访问。
答案 3 :(得分:0)
/ *向集合视图提供约束,并在tableviewcell页面中创建collectionviewcell出口,并在同一tableviewcell页面中创建collectionviewheight约束出口。 在tableviewcell页面* /
中像这样 class homeServiceTableCell6: UITableViewCell {
@IBOutlet weak var dealsCollectionView: UICollectionView!
@IBOutlet weak var dealsCollectionHeight: NSLayoutConstraint!
@IBOutlet weak var dealsImage: UIImageView!
like this in the main page cellforRowAt indexPath function
func tableView (_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = homeServiceTable.dequeueReusableCell ( withIdentifier: "homeServiceTableCell6" ) as! homeServiceTableCell6
cell.dealsImage.image = UIImage(named: "deals.png")
cell.dealsCollectionView.tag = indexPath.row
cell.dealsCollectionView.delegate = self
cell.dealsCollectionView.dataSource = self
cell.dealsCollectionView.reloadData()
cell.dealsCollectionHeight.constant = cell.dealsCollectionView.collectionViewLayout.collectionViewContentSize.height
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
//最后将这一行添加到viewWillAppear函数中
override func viewWillAppear(_ animated: Bool) {
self.homeServiceTable.layoutSubviews()
}