首页 > 解决方案 > 为集合视图单元设置自动大小计算时出现问题

问题描述

我在集合视图中有 2 个部分。

第一节没有标题,并且一个跨越屏幕宽度的单元格和高度应该根据其中的内容(比如一些标签,一个在另一个之下)。

第二部分有一个标题视图和 20 个单元格。标题视图跨越屏幕的宽度。单元格将像 2 水平 x 10 垂直。单元格的宽度将是屏幕大小除以 2 和静态高度,例如 150。

因此,根据要求,我需要第一部分的单元格高度是动态的,而第二部分的单元格高度是静态的。此外,该部分应在滚动时固定到顶部。

func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 2
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    if section == 0 {
        return 1
    }
    return 20
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    if indexPath.section == 0 {
        if let oneCell = collectionView.dequeueReusableCell(withReuseIdentifier: "OneCell", for: indexPath) as? OneCell {
            oneCell.setData()
            return oneCell
        }
    }
    if let twoCell = collectionView.dequeueReusableCell(withReuseIdentifier: "TwoCell", for: indexPath) as? TwoCell {
        return twoCell
    }
    return UICollectionViewCell()
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
    if section == 0 {
        return CGSize.zero
    }
    return CGSize(width: collectionView.frame.size.width, height: 96)
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
    if section == 0 {
        return CGSize.zero
    }
    return CGSize(width: collectionView.frame.size.width, height: 96)
}

func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
    if kind == UICollectionView.elementKindSectionHeader && indexPath.section == 1 {
        if let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "TwoHeader", for: indexPath) as? TwoHeader {
            return header
        }
    }
    if kind == UICollectionView.elementKindSectionFooter && indexPath.section == 1 {
        if let footerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "TwoFooter", for: indexPath) as? TwoFooter {
            return footerView
        }
    }
    return UICollectionReusableView()
}


    // IS THIS METHOD EVEN NEEDED FOR SITUATION SIZE CALCULATION US AUTOMATIC?
//    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
//        if indexPath.section == 0 {
//            return CGSize(width: collectionView.frame.size.width, height: collectionView.frame.size.height)
//        }
//        return CGSize(width: (collectionView.frame.size.width - 12) / 2, height: 150)
//    }

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    if section == 0 {
        return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
    }
    return UIEdgeInsets(top: 4, left: 4,  bottom: 4, right: 4)
}

我正在使用此方法从 UICollectionViewCell 子类中返回每个单元格所需的大小

第一节细胞

override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {

        let targetSize = CGSize(width: UIApplication.shared.windows[0].bounds.width, height: 0)
        layoutAttributes.frame.size = contentView.systemLayoutSizeFitting( targetSize, withHorizontalFittingPriority: .required, verticalFittingPriority: .fittingSizeLevel)
        return layoutAttributes
    }

第二节单元格

override func preferredLayoutAttributesFitting(
        _ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {

        // Full width - 3 times the collectionview padding (left inset(4) + right inset(4) + centre interim space(4))
        let width = (UIApplication.shared.windows[0].bounds.width - 12) / 2
        let targetSize = CGSize(width: width, height: 150)
        layoutAttributes.frame.size = targetSize
        return layoutAttributes
    }

问题

集合视图的滚动性能消失了。它颤抖着。节标题跳到顶部而不是平滑运动。集合视图反弹现在正在发生。如果我们在单元格中添加更复杂的 UI 以及增加单元格的数量,问题会更加突出。似乎集合视图在滚动时无法计算内容高度。我在这里想念什么?是什么导致了这个问题?

我创建了一个项目,仅使用一些标签来显示问题。可以在这里找到。请务必安装 pod。

提前致谢。

标签: iosswiftuicollectionviewuicollectionviewcell

解决方案


推荐阅读