Collection view grid last row appears differently despite equal widths - swift iOS

DrW*_*hat 5 ios uicollectionview uicollectionviewlayout swift

I've a fixed grid of collection view cells (UICollectionView) but the cells in the bottom row always appears with a slightly smaller width on screen. The frame size (or bounds) and calculated width used within collectionViewLayout: UICollectionViewLayout sizeForItemAt are the same for all rows.

在此处输入图片说明

        func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
    let settings = currentContents[indexPath.item]
    let height = CGFloat(30)

    // /sf/ask/3844065921/
    var cellWidth = CGFloat()
    let availableWidth = collectionView.bounds.size.width
    print("available width", availableWidth)
    let minimumWidth = floor(availableWidth / collectionContents.cellsPerRow5)
    print("minmum width", minimumWidth)
    cellWidth = minimumWidth * settings.portion - 1
    print("cell width", cellWidth)

    return CGSize(width: cellWidth, height: height)
}
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

I'd like to get the bottom row to line up with the other rows, but can't imagine what is happening that is changing the widths after returning the value in the layout delegate method (or how to fix).

DrW*_*hat 0

我发现的最好方法是在计算初始列宽后捕获剩余空间(负 1 以避免四舍五入),然后将剩余空间用于其他列。

对于两列示例:

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
    if indexPath.item == 0 || indexPath.item == 1
    { rowHeight = 40 }
    else { rowHeight = 30 }
    var cellWidth = CGFloat()
    let minimumWidth = floor(availableWidth / numberOfColumns)
    var columnPortion = CGFloat()
    let columnNumber = indexPath.item % Int(numberOfColumns)
    switch columnNumber
    {
    case 0:
        columnPortion = columnPortion1
        cellWidth = minimumWidth * columnPortion - 10
        remainder = availableWidth - cellWidth - 1
    case 1:
        columnPortion = columnPortionFinal
        cellWidth = remainder
    default:
        break
    }
    return CGSize(width: cellWidth, height: rowHeight)
}
Run Code Online (Sandbox Code Playgroud)