首页 > 解决方案 > 如何使 collectionView 中的可折叠标题与 Facebook 标题相同?

问题描述

伙计们,我需要制作一个 collectionView 标题,它应该可以工作,因为当我向上滚动标题折叠直到特定点然后折叠停止并且滚动条像折叠之前一样继续滚动,你可以在 Facebook android 应用程序中检查这种行为,我需要使用swift在iOS中实现同样的事情,我已经尝试使用collectionView的委托方法“scrollViewDidScroll”,这是myCode

func scrollViewDidScroll(_ scrollView: UIScrollView) {
     let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout
        if scrollView.contentOffset.y > 199 {
            headerHeight = 101
            layout?.sectionHeadersPinToVisibleBounds = true
            collectionView.reloadData()
        } else if scrollView.contentOffset.y < 199 {
            headerHeight = 300
            layout?.sectionHeadersPinToVisibleBounds = false
            collectionView.reloadData()

        }
    }

PS:我原来的标题高度是300,199是滚动后需要隐藏的部分,101值是滚动后所需的标题高度

当我实现这段代码时,一切正常,但问题是当我达到 199 的 contentoffset.y 时,collectionView 的单元格会向上移动一点,当我向下滚动 < 199 时,单元格会向下移动,这很快移动立即发生,不顺利,这是糟糕的用户体验。请问这样的bug怎么解决?

标签: iosswiftuicollectionviewscrollview

解决方案


为此,您需要有一个节标题UICollectionReusableView

故事板布局

UICollectionViewDelegateFlowLayout

func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
        
        switch kind {
        case UICollectionView.elementKindSectionHeader:
            guard
                let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "BlueHeaderCollectionReusableView", for: indexPath) as? BlueHeaderCollectionReusableView else {
                    fatalError("Invalid view type")
            }
            return headerView
        default:
            assert(false, "Invalid element type")
        }
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
        
        return CGSize(width: collectionView.frame.width, height: calculateHeight())
    }

要计算高度,您可以使用以下功能

let min: CGFloat = 100
let max: CGFloat = 250

    func calculateHeight() -> CGFloat {
        let scroll = self.collectionView.contentOffset.y
        
        let heightTemp = max - scroll
        
        if  heightTemp > max {
            return max
        } else if heightTemp < min {
            return min
        } else {
            return heightTemp
        }
    }

结果

输出


推荐阅读