【问题标题】:Collectionview Fixed Cell SpacingCollectionview 固定单元格间距
【发布时间】:2021-05-05 05:06:39
【问题描述】:

我一直在寻找如何使UICollectionView 在其单元格之间具有固定间距,但到目前为止还没有找到解决方案。

我有一个UICollectionView,它由两列组成,所有单元格的宽度相同,但高度不同。我在这个UICollectionView 中只有一个部分。

我已将最小间距设置为 10(这是我想要的垂直单元格之间的值),但系统似乎随机拉伸垂直空间。

我想要实现的是iPad版Wikipedia的效果:不同的文章图块具有相同的宽度,但可以根据需要调整高度,但所有单元格都是垂直均匀的空间。 (我不介意在最后留空间,但我不希望中间有多余的空间)

我应该如何做到这一点?如果可以轻松迁移现有的UICollectionViews(当然它是开源的),我会接受第三方库。

【问题讨论】:

  • 使用 UICollectionViewDelegateFlowLayout 的委托方法。你的问题解决了

标签: ios swift uicollectionview


【解决方案1】:

在 Swift 3 中, 您可以在collectionView 中为单元格间距实现此委托方法:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize{
    // Give cell width and height
    return CGSize(width: 750, height: 320)
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat{
    // splace between two cell horizonatally
    return 50
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat{
    // splace between two cell vertically
    return 100
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets{
    // give space top left bottom and right for cells
    return UIEdgeInsets(top: 0, left: 100, bottom: 100, right: 100)
}

【讨论】:

  • 感谢您的回复!由于服务器暂时不可用,我无法测试你的答案,但我会尽快测试。
  • 奇怪的是,没有任何变化。有什么我可能错过的吗?
  • 请检查所有委托是否正确设置以及是否调用了这些方法。
【解决方案2】:

好吧,毕竟我设置的间距是单元格之间的MINIMUM间距。 collectionView 可以使用对齐同一行上的单元格所需的任何间距,只要它不小于最小值。

【讨论】:

    【解决方案3】:

    如果你想在 UICollectionView 上固定项目间的间距,你可以使用下面的自定义布局。注意:我为固定高度单元格和 .vertical 滚动方向创建了此布局。

    class CollectionViewFlowLayout: UICollectionViewFlowLayout {
    
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        guard let layoutAttributes = super.layoutAttributesForElements(in: rect) else {
            return nil
        }
        
        var startX: CGFloat = 0.0
        var startY: CGFloat = 0.0
        let contentWidth = collectionView?.frame.width ?? 0
        
        for layoutAttributes in layoutAttributes {
            let size = layoutAttributes.size
            if (startX + size.width + minimumInteritemSpacing) > contentWidth {
                startX = 0
                startY += size.height
                startY += minimumLineSpacing
            }
            let origin = CGPoint(x: startX, y: startY)
            let frame = CGRect(origin: origin, size: size)
            layoutAttributes.frame = frame
            startX += size.width + minimumInteritemSpacing
        }
        return layoutAttributes
    }
    

    }

    【讨论】: