UITableViewCell内部的非滚动UICollectionView动态高度

时间:2019-03-08 10:34:39

标签: ios swift uitableview uicollectionview autolayout

我在as.logical(TRUE + FALSE)内添加了UICollectionView,为此我创建了UITableViewCell文件。检查以下图片:

UITableView Xib

您可以在上图中看到所有视图的层次结构和约束。

  

注意:我已禁用垂直和水平集合视图   滚动,因为我想动态增加XIB的高度。因此,我已经采用了收集视图的高度约束的出口,并根据收集视图中可用的项目以编程方式对其进行了更改。

收藏夹视图的项目大小(如果固定),宽度与收藏夹视图成比例,高度为30

我已使用以下代码在我的表格视图中注册了该xib。

UITableViewCell

这是我的self.tblSubCategory.register(SubCategoryTVC.Nib(), forCellReuseIdentifier: "SubCategoryTVC") 代码:

SubCategoryTVC

UITableViewDataSource:

class SubCategoryTVC: UITableViewCell {

    @IBOutlet weak var categoryView                 : UIView!
    @IBOutlet weak var categoryImageView            : UIView!
    @IBOutlet weak var imgCategory                  : UIImageView!
    @IBOutlet weak var lblCategoryName              : UILabel!

    @IBOutlet weak var cvSubcategory                : UICollectionView!

    // MARK: Constrains's Outlet
    @IBOutlet weak var const_cvSubcategory_height   : NSLayoutConstraint!


    class func Nib() -> UINib {
        return UINib(nibName: "SubCategoryTVC", bundle: nil)
    }

    func setCollectionView(dataSourceDelegate: UICollectionViewDataSource & UICollectionViewDelegate, forRow row: Int) {
        self.cvSubcategory.delegate = dataSourceDelegate
        self.cvSubcategory.dataSource = dataSourceDelegate
        self.cvSubcategory.tag = row
        self.cvSubcategory.reloadData()
    }

    override func awakeFromNib() {
        super.awakeFromNib()
    }
}

UITableViewDelegate:

extension SignupSecondStepVC: UITableViewDataSource {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 5
    }

    //------------------------------------------------------------------------------

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "SubCategoryTVC", for: indexPath) as! SubCategoryTVC

        cell.lblCategoryName.text = "Category \(indexPath.row)"

        cell.cvSubcategory.register(SubCategoryCVC.Nib(), forCellWithReuseIdentifier: "SubCategoryCVC")

        return cell
    }
}

以上extension SignupSecondStepVC: UITableViewDelegate { func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { guard let subCategoryCell = cell as? SubCategoryTVC else { return } // This line of code set dataSource and delegate to `SignupSecondStepVC` instead of `SubCategoryTVC` subCategoryCell.setCollectionView(dataSourceDelegate: self, forRow: indexPath.row) subCategoryCell.cvSubcategory.setNeedsLayout() // This will change height of collection view based on item available. subCategoryCell.const_cvSubcategory_height.constant = 30 * 5 subCategoryCell.cvSubcategory.setNeedsLayout() subCategoryCell.contentView.layoutIfNeeded() } //------------------------------------------------------------------------------ func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return UITableView.automaticDimension } //------------------------------------------------------------------------------ func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { return UITableView.automaticDimension } } 的代码,请参见以下UITableView的代码

UICollectionViewDataSource:

UICollectionView

UICollectionViewDelegateFlowLayout:

extension SignupSecondStepVC: UICollectionViewDataSource {

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 5
    }

    //------------------------------------------------------------------------------

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "SubCategoryCVC", for: indexPath) as! SubCategoryCVC

        cell.btnSelection.setCornerRadius(radius: cell.btnSelection.frame.size.height / 2)
        cell.lblSubCategoryName.text = "SubCategory \(indexPath.row)"

        return cell
    }
}

完成所有这些操作后,单元格加载和UI出现问题。第一次运行应用程序并加载数据时,出现UI问题,而数据加载不正确。观看以下视频,以便您了解我的实际问题。

Issue Video

请帮助我解决此问题。

1 个答案:

答案 0 :(得分:2)

您需要将您的collectionView委托/数据源与TableViewCell绑定,并需要在tableViewcell中使用以下func。确保关闭CollectionView滚动。

override func systemLayoutSizeFitting(_ targetSize: CGSize, withHorizontalFittingPriority horizontalFittingPriority: UILayoutPriority, verticalFittingPriority: UILayoutPriority) -> CGSize {

    self.layoutIfNeeded()
    let contentSize = self.cvSubcategory.collectionViewLayout.collectionViewContentSize
    if self.cvSubcategory.numberOfItems(inSection: 0) < 4 {
        return CGSize(width: contentSize.width, height: 120) // Static height if colview is not fitted properly.
    }

    return CGSize(width: contentSize.width, height: contentSize.height + 20) // 20 is the margin of the collectinview with top and bottom
}

您的项目示例解决方案:https://github.com/thedahiyaboy/DynamicCollectionApp


出于将来的目的,您可以参考这篇文章:Dynamic CollectionViewCell In TableViewCell Swift