集合视图更改间距

时间:2018-08-09 11:26:46

标签: ios swift collectionview

问题:如果流派或国家(集合视图单元)的行数超过一,则该行的最后一个流派/国家(单元)会被绑定并导致空间增加。

ScreenShot

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)
    _ = cell.subviews.compactMap { $0.removeFromSuperview() }
    cell.layer.borderColor = Colors.textPoster.color().cgColor
    cell.layer.borderWidth = 0.5
    cell.layer.cornerRadius = 3

    let label = self.label()

    if indexPath.section == 0 {
        label.text = ganres[indexPath.row]
    } else {
        label.text = countries[indexPath.row]
    }

    label.sizeToFit()
    cell.addSubview(label)
    label.centerXAnchor.constraint(equalTo: cell.centerXAnchor).isActive = true
    label.centerYAnchor.constraint(equalTo: cell.centerYAnchor).isActive = true
    return cell
}

// MARK: UICollectionViewDelegate
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
    return 8
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
    return 8
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
    return CGSize(width: 0, height: 16)
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let text = indexPath.section == 0 ? ganres[indexPath.row] : countries[indexPath.row]
    let size = CGSize(width: text.width(withConstrainedHeight: .greatestFiniteMagnitude, font: labelFont) + space, height: text.height(withConstrainedWidth: .greatestFiniteMagnitude, font: labelFont) + space)

    return size
}

1 个答案:

答案 0 :(得分:0)

我找到了答案here。此FlowLayout使用minimumInteritemSpacing进行左对齐。请确保自行设置。

class LeftAlignedCollectionViewFlowLayout: UICollectionViewFlowLayout {
var cache: [IndexPath : UICollectionViewLayoutAttributes] = [:]

override func prepare() {
    cache = [:]
    super.prepare()
}

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
    guard let originalAttributes = super.layoutAttributesForElements(in: rect) else {
        return nil
    }
    var attributes = originalAttributes.map { $0.copy() as! UICollectionViewLayoutAttributes }
    var attributesByGraphicalRow: [[UICollectionViewLayoutAttributes]] = []
    var y: CGFloat = 0
    var currentRow: [UICollectionViewLayoutAttributes] = []

    func changeAttributesOfRow(_ row: [UICollectionViewLayoutAttributes]) {
        var minX: CGFloat = 0

        for rowAttribute in currentRow {
            let oldFrame = rowAttribute.frame
            let newOrigin = CGPoint(x: minX, y: oldFrame.origin.y)
            let newFrame = CGRect(origin: newOrigin, size: oldFrame.size)
            rowAttribute.frame = newFrame
            minX += (newFrame.size.width + self.minimumInteritemSpacing)
        }
    }

    for attribute in attributes {
        if attribute.frame.origin.y > y {
            // new row starts
            changeAttributesOfRow(currentRow)
            attributesByGraphicalRow.append(currentRow)
            currentRow = []
            y = attribute.frame.origin.y
        }
        currentRow.append(attribute)
    }
    if currentRow.count > 0 {
        // last row isn't appended in for loop
        changeAttributesOfRow(currentRow)
        attributesByGraphicalRow.append(currentRow)
    }

    for attribute in attributes {
        cache[attribute.indexPath] = attribute
    }
    return attributes
}

override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
    if let attribute = cache[indexPath] {
        return attribute
    }
    // now what??
    return super.layoutAttributesForItem(at: indexPath)
}

}