UICollectionView 动态单元格高度(Pinterest 布局)

Posted

技术标签:

【中文标题】UICollectionView 动态单元格高度(Pinterest 布局)【英文标题】:UICollectionView dynamic cell height (Pinterest layout) 【发布时间】:2017-01-17 09:17:31 【问题描述】:

我正在尝试在我的应用中实现 Pinterest 布局

我使用以下委托方法来实现并动态设置单元格高度

 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
    let boundingRect =  CGRect(x: 0, y: 0, width: self.view.frame.size.width / 2 - 20, height: CGFloat(MAXFLOAT))
    let data = articles[indexPath.row]
    let rect  = AVMakeRect(aspectRatio: (data.coverImage?.size)!, insideRect: boundingRect)
    return CGSize(width: rect.width, height: rect.height + 120) // Added 120 for a description I will add later 

但我得到了以下结果:

灰色背景是单元格的背景,可以看到每个单元格都有自己的高度(如预期的那样) 但是有额外的空白我不知道如何删除。

我该如何解决这个问题?

【问题讨论】:

没有人试过这个?为什么没有答案? 你找到解决办法了吗? 【参考方案1】:

您可以查看 raywenderlich 教程:

https://www.raywenderlich.com/164608/uicollectionview-custom-layout-tutorial-pinterest-2

如果您想在到达最后一个单元格时加载新数据,那么您必须编辑一些代码。

在 PinterestLayout.swift 中,进行以下更改:

 guard cache.isEmpty == true, let collectionView =   collectionView else 
        return
    

 guard let collectionView = collectionView else 
        return
     

// 这个文件名可能和你的不一样

在 PhotoStreamViewController.swift 中添加如下代码:

   override func collectionView(_ collectionView:  UICollectionView, willDisplay cell: UICollectionViewCell,  forItemAt indexPath: IndexPath) 
      if (indexPath.row == photos.count - 1 ) 
     //it's your last cell

     // Add more data to the array according your requirement

     // After adding data reload collection view
        collectionView.reloadData()
        
    

【讨论】:

【参考方案2】:

您的UICollectionView 布局不正确。从情节提要或通过CollectionViewDelegateFlowLayout 方法删除单元格间距和列间距。

 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat 
    return CGFloat()// Your Value


func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat 
     return CGFloat()// Your Value
    

【讨论】:

【参考方案3】:

在我的情况下,ChatMessageController 是如何工作的,每个单元格可以有不同的高度

    首先我们需要使用 UICollectionViewFlowLayout

    扩展 ChatMessageController func createLayout() -> UICollectionViewLayout

         let layout: UICollectionViewFlowLayout = 
             let layout = UICollectionViewFlowLayout()
             let width = UIScreen.main.bounds.size.width
             layout.estimatedItemSize = CGSize(width: width, height: 80)
             return layout
         ()
    
         return layout
     
    

    然后在 UICollectionViewCell 中像这样覆盖 systemLayoutSizeFitting:

    覆盖 func systemLayoutSizeFitting(_ targetSize: CGSize, withHorizo​​ntalFittingPriority Horizo​​ntalFittingPriority: UILayoutPriority, verticalFittingPriority: UILayoutPriority) -> CGSize width.constant = bounds.size.width 返回 contentView.systemLayoutSizeFitting(CGSize(width: targetSize.width, height: getHeight()))

其中 getHeight 是根据内容计算实际单元格高度的函数,例如:

    private func getHeight() -> CGFloat 
            let text = label.text ?? ""
            
            let constraintRect = CGSize(width: 0.75 * contentView.frame.width,
                                        height: .greatestFiniteMagnitude)
            let boundingBox = text.boundingRect(with: constraintRect,
                                                options: .usesLineFragmentOrigin,
                                                attributes: [.font: label.font as Any],
                                                context: nil)
            
            let bubbleSize = CGSize(width: boundingBox.width + d.w(30), height: boundingBox.height + d.h(30))
            
            let height = bubbleSize.height
            
            return height
        


【讨论】:

以上是关于UICollectionView 动态单元格高度(Pinterest 布局)的主要内容,如果未能解决你的问题,请参考以下文章

UICollectionView 动态单元格高度(Pinterest 布局)

如何在 iOS 中动态更改 UICollectionView 单元格高度

动态 UICollectionView 单元格高度

具有动态高度和半宽的 UICollectionview 单元格

UICollectionView 单元格在swift中使用约束固定宽度和动态高度

如何在 Swift 中动态更改包含 UICollectionView 单元格的 UITableView 单元格的高度?