UITolViewView内部的UICollectionView如何根据屏幕大小调整tableview单元格高度

时间:2017-03-25 00:45:25

标签: ios swift uitableview uicollectionview

我有以下布局

  • 的UITableView
    • UITableViewCell(类:CategoryCell)
      • 标签
      • 按钮
      • UICollectionView
        • UICollectionViewCell(class:ItemCell)
          • 的UIImageView
          • 的UILabel

我正在尝试使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)

4 个答案:

答案 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()
    }