集合视图单元格中的集合视图适合内容

Posted

技术标签:

【中文标题】集合视图单元格中的集合视图适合内容【英文标题】:Collectionview in collectionview cell fitting to content 【发布时间】:2019-01-19 23:39:22 【问题描述】:

我有一个包含两个部分的集合视图,每个部分都有一个项目。部分中的单元格包含集合视图,我需要将高度单元格适合内容集合视图。

我的第一部分的高度固定为 120,因为它是水平的 collectionview 并且高度没有改变。但是对于第二部分,元素的数量可以更改,我需要显示所有项目(collectionview 的 scrollEnabled 为 false,scrolldirecton 为垂直)。

我的问题是我需要显示一个包含两个滚动方向依赖部分的集合视图,并显示垂直集合视图的所有项目。

当我做collectionview.collectionViewLayout.collectionViewContentSize.height 时,我有很好的高度,但我不知道如何将这个高度传递给父视图控制器。我搜索了一个动态解决方案来解决这个问题。

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout 

    // MARK: - UICollectionViewDataSource

    func numberOfSections(in collectionView: UICollectionView) -> Int 
        return presenter.numberOfSections // == 2
    

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
        return presenter.numberOfItemsInSection // == 1
    

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
        let cell = collectionView.dequeueCell(InlineDisplayCollectionViewCell.self, for: indexPath)
        configureCell(cell, at: indexPath)

        return cell
    

    // MARK: - UICollectionViewDelegateFlowLayout

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
        let type = presenter.typeAtIndexPath(indexPath)
        switch type 
        case .city:
            return CGSize(width: collectionView.frame.width, height: 120)
        case .suggestion:
            return CGSize(width: collectionView.frame.width, height: 820)
        default:
            return CGSize.zero
        
    





class InlineDisplayCollectionViewCell: UICollectionViewCell, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout 

    @IBOutlet weak var collectionView: UICollectionView!

    var itemType: ItemModelCollectionType! = .city 
        didSet 
            updateCell()
        
    
    var cities: [City]? 
        didSet 
            collectionView.reloadData()
        
    
    var suggestions: [Suggestion]? 
        didSet 
            collectionView.reloadData()
        
    

    override func awakeFromNib() 
        super.awakeFromNib()

        configureView()
    

    // MARK: - UICollectionViewDataSource

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
        return itemType == .city ? cities?.count ?? 0 : suggestions?.count ?? 0
    

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
        let cell: UICollectionViewCell
        if itemType == .city 
            let cityCell = collectionView.dequeueCell(CityCollectionViewCell.self, for: indexPath)
            configure(cell: cityCell, at: indexPath)
            cell = cityCell
         else 
            let suggestionCell = collectionView.dequeueCell(SquareCollectionViewCell.self, for: indexPath)
            configure(cell: suggestionCell, at: indexPath)
            cell = suggestionCell
        
        return cell
    

    // MARK: - UICollectionViewDelegateFlowLayout

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat 
        return itemType == .city ? 10 : 10
    

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat 
        return itemType == .city ? 0 : 10
    

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
        let size: CGSize
        if itemType == .city 
            size = CGSize(width: 100, height: 120)
         else 
            let width = (collectionView.frame.width - (collectionView.contentInset.left + collectionView.contentInset.right) - 10) * 0.5
            let height = width
            size = CGSize(width: width, height: height)
        

        return size
    

    // MARK: - Private functions

    private func configureView() 
        collectionView.delegate = self
        collectionView.dataSource = self
        collectionView.contentInset = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20)
        collectionView.registerNib(CityCollectionViewCell.self, bundle: nil)
        collectionView.registerNib(SquareCollectionViewCell.self, bundle: nil)
    

    private func updateCell() 
        if let flowLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout 
            flowLayout.scrollDirection = itemType == .city ? .horizontal : .vertical
        
        collectionView.isScrollEnabled = itemType == .city
    

    private func configure(cell: CityCollectionViewCell, at indexPath: IndexPath) 
        guard let city = cities?[indexPath.row] else  return 
        cell.configure(with: city)
    

    private func configure(cell: SquareCollectionViewCell, at indexPath: IndexPath) 
        guard let suggestion = suggestions?[indexPath.row] else  return 
        cell.configure(with: suggestion)
    


【问题讨论】:

【参考方案1】:

你不能那样做。 CollectionView 单元格出列并动态重用。最好的方法是在同一个 CollectionView 中使用不同类型的单元格。

请查看我在此主题上发布的问题:Get the sum of all collectionViewCells' heights inside a CollectionView 和 Multiple Cells for Comments and Reply in a CollectionView

【讨论】:

【参考方案2】:

很遗憾,您不能这样做。但是你的简历中可以有不同类型的单元格。您也可以在名为“cellForItemAt”的函数中对其进行修改。

【讨论】:

以上是关于集合视图单元格中的集合视图适合内容的主要内容,如果未能解决你的问题,请参考以下文章

集合视图单元格中的动态按钮宽度

如何更改集合视图单元格中的图像视图

表格单元格中的集合视图。这是重用的错误

如何通过单击更改集合视图单元格中的标签颜色

为啥两个表格视图单元格中的两个集合视图在 Swift 4 中不起作用?

如何从集合视图中的不可见单元格中删除自定义视图