UICollectionView 单元格未对齐

Posted

技术标签:

【中文标题】UICollectionView 单元格未对齐【英文标题】:UICollectionView cells are misaligned 【发布时间】:2018-01-10 19:09:47 【问题描述】:

屏幕截图显示了UICollectionView 的一部分。集合视图的宽度为294.0,其最小项间距为0。每行单元格的宽度为117.0, 58.0, 58.0,58.0。这些宽度是由UICollectionViewDelegateFlowLayout 动态计算的,我相信这是必要的,因为并非所有单元格都具有相同的宽度。垂直的黑线是集合视图的背景。由于某种原因,最后一行中的单元格与其他行中的单元格不对齐。什么可能导致此问题,我该如何解决?

编辑:代码在这里:https://gist.github.com/csimmons0/ef7933730905d57fb347d803df2d77dd

【问题讨论】:

我找到了一种解决方法:添加一个高度等于一个像素且宽度等于集合视图宽度的虚拟单元格。一旦我这样做,真正的细胞就会对齐。不过,更清洁的解决方案会很好。 你想要单元格之间的空间吗?如果是,为什么minimumInteritemSpacing 不等于 1? @beyowulf 将 minimumInteritemSpacing 设置为非零值并不能解决问题。集合视图仍然在最后一行的最后一排将任何剩余空间聚集在一起,与其他行相反,它似乎分散了剩余空间。 发布您的代码。如有必要,所有这些。没有人可以帮助您提供的内容。我的观点更重要的是,如果您想要单元格之间有一个点空间,为什么要设置 minimumInteritemSpacing == 0,因为您至少希望项目之间有 1 个点。 @beyowulf 我用代码添加了一个指向要点的链接。理想情况下,项目间不会有任何间距,但我找不到一种方法来实现这一点。当我试图使单元格的总宽度等于集合视图的宽度时,某些手机上的布局与预期的一样,但在其他手机上,四个单元格不能排成一行。我认为这是由于浮点不精确问题造成的,这就是为什么我开始将单元格的宽度舍入为零的原因。只要四个单元格排成一行并且列对齐,我不在乎它们之间有多少空间。 【参考方案1】:

我认为如果您将值设置为 minimumInteritemSpacing 并且您的单元格大小并不能真正反映 minimumInteritemSpacing,就会发生这种情况。即)如果您的单元格大小创建项目间距 1 并且如果您将 minimumInteritemSpacing 设置为 0,则会导致您遇到的问题。希望有人可以解释这一点,但这是我在使用自己的收藏视图后发现的。

class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout 

    @IBOutlet weak var collectionView: UICollectionView!

    override func viewDidLoad() 
        super.viewDidLoad()
        collectionView.delegate = self
        collectionView.dataSource = self
        if let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout 
            layout.minimumInteritemSpacing = minItemSpacing
        

        collectionView.register(DemoCell.self, forCellWithReuseIdentifier: "DemoCell")

        collectionView.reloadData()
    

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
        return numberOfRows * numberOfColumns
    

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "DemoCell", for: indexPath) as! DemoCell
        return cell
    

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
        if indexPath.item % 4 == 0 
            return CGSize(width: firstColumnWidth, height: view.frame.size.height / CGFloat(numberOfRows))
         else 
            return CGSize(width: regularColumnWidth, height: view.frame.size.height / CGFloat(numberOfRows))
        
    

    var minItemSpacing: CGFloat 
        return 1
    

    var numberOfColumns: Int 
        return 4
    

    var numberOfRows: Int 
        return 8
    

    var firstColumnWidth: CGFloat 
        return 117
    

    var regularColumnWidth: CGFloat 
        return (collectionView.frame.size.width - firstColumnWidth - CGFloat(numberOfColumns - 1) * minItemSpacing) / CGFloat(numberOfColumns - 1)
    


class DemoCell: UICollectionViewCell 

    override init(frame: CGRect) 
        super.init(frame: frame)
        backgroundColor = .red
    

    required init?(coder aDecoder: NSCoder) 
        fatalError("init(coder:) has not been implemented")
    

此代码完美运行。如果更改 layout.minimumInteritemSpacing = 0,则最后一行的单元格都向左对齐。我创建了变量,以便您可以使用它。希望对您有所帮助。

【讨论】:

以上是关于UICollectionView 单元格未对齐的主要内容,如果未能解决你的问题,请参考以下文章

UICollectionView 单元格未在 reloadData 上清除

UICollectionView 自定义单元格未重新加载

UICollectionView 正在显示,但单元格未快速显示

UICollectionView 具有自调整大小的单元格未正确计算 contentSize

UICollectionView 的不可见单元格未被取消选择 - Swift

引导表单元格未对齐