iOS ColleCtionView 如何让cell 不重复创建并且只在展示的时候才创建

前言

使用 collectionView 一屏只展示一个 cell ,一次只加载当前 cell,还要能够缓存已加载过的 cell ,使 cell 不重复加载,听着好像就是将 collectionView 的复用机制禁用掉。用collectionView 实现这个需求,就出现了两个冲突点,一个是collectionView 会预加载后面的 cell ,另一个是会释放掉没在屏幕中显示的 cell 。
示例
请添加图片描述

思路

  1. 将加载过的视图用一个字典存起来
  2. 当 cell 从重用池中取出来后,将字典中存放的对应视图 加载到 cell 上展示
  3. 当从字典中没有取到对应的视图时,就去创建新视图

主要实现代码

缓存的字典

var validViewDict:[Int:CommentView] = [:]

加载 cell

  func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
        cell.contentView.subviews.forEach { $0.removeFromSuperview()}
        
        if let validView = validViewDict[indexPath.item] {
            validView.frame = cell.contentView.bounds
            cell.contentView.addSubview(validView)
        }
        
        return cell
    }

创建视图时机

   func scrollViewDidScroll(_ scrollView: UIScrollView) {
        guard scrollView.isTracking || scrollView.isDragging else {
            return
        }
        let percent = scrollView.contentOffset.x/scrollView.bounds.size.width
        let maxCount = Int(round(scrollView.contentSize.width/scrollView.bounds.size.width))
        var leftIndex = Int(floor(Double(percent)))
        leftIndex = max(0, min(maxCount - 1, leftIndex))
        let rightIndex = leftIndex + 1;
        if percent < 0 || rightIndex >= maxCount {
            return
        }
        let remainderRatio = percent - CGFloat(leftIndex)

        if rightIndex == currentIndex {
            //当前选中的在右边,用户正在从右边往左边滑动
            if validViewDict[leftIndex] == nil && remainderRatio < (1 - initListPercent) {
                initListIfNeeded(at: leftIndex)
            }
            
        }else {
            //当前选中的在左边,用户正在从左边往右边滑动
            if validViewDict[rightIndex] == nil && remainderRatio > initListPercent {
                initListIfNeeded(at: rightIndex)
                currentIndex = rightIndex
            }
        }
        
    }

创建视图并存入字典

    func initListIfNeeded(at index: Int) {
      
        var existedView = validViewDict[index]
        if existedView != nil {
            //列表已经创建好了
            return
        }
        existedView = initValidView(initViewAt: index)
        guard let commentView = existedView else {
            return
        }
        
        validViewDict[index] = commentView
        
        let cell = collectView.cellForItem(at: IndexPath(item: index, section: 0))
        cell?.contentView.subviews.forEach { $0.removeFromSuperview() }
        commentView.frame = cell?.contentView.bounds ?? CGRect.zero
        cell?.contentView.addSubview(commentView)
    }

结语

使用字典保存加载的视图,每次加载 cell 时先移除子视图,再加载字典中的视图,避免了复用带来的界面展示内容不对的问题。在滚动代理 scrollViewDidScroll 中计算创建视图的时机,保证只创建当前展示的cell 的视图。这样我们就巧妙的实现了“如何让cell 不重复创建并且只在展示的时候才创建”。


感谢您的阅读和参与,HH思无邪愿与您一起在技术的道路上不断探索。如果您喜欢这篇文章,不妨留下您宝贵的赞!如果您对文章有任何疑问或建议,欢迎在评论区留言,我会第一时间处理,您的支持是我前行的动力,愿我们都能成为更好的自己!

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
iOSCollectionView是一种强大的界面展示控件,它允许我们展示多个横向或纵向滚动的项。而Section Header是CollectionView中的一个重要组成部分,它可以用来展示每个分区的标题或其他相关信息。 在iOS中使用CollectionView的时候,我们可以通过实现UICollectionViewDelegateFlowLayout协议来设置每个分区的大小、间距等布局属性。而Section Header则需要通过实现UICollectionViewDelegate的collectionView:viewForSupplementaryElementOfKind:atIndexPath:方法来自定义。 首先,我们需要创建一个UICollectionReusableView类的子类作为Section Header的视图。然后,在collectionView:viewForSupplementaryElementOfKind:atIndexPath:方法中,我们需要判断elementKind是否为UICollectionElementKindSectionHeader,并根据需要从重用队列中获取Section Header的视图对象。 接下来,我们可以设置Section Header的标题、背景色、字体颜色等视觉效果。例如,我们可以使用UILabel来展示标题,并通过设置UILabel的text属性来显示每个分区的标题。如果需要更加丰富的自定义效果,我们还可以使用自定义的视图来展示Section Header。 最后,我们需要在UICollectionViewFlowLayout中设置sectionHeadersPinToVisibleBounds属性为true,以便在滚动时固定Section Header的位置。这样,当用户滚动CollectionView时,Section Header会始终显示在顶部,增加了用户的使用体验。 综上所述,iOSCollectionView提供了强大的支持来展示多个滚动项,而Section Header则可以用来展示每个分区的相关信息。通过实现UICollectionViewDelegate的collectionView:viewForSupplementaryElementOfKind:atIndexPath:方法,我们可以自定义Section Header的视图,并通过UICollectionViewFlowLayout来设置其布局等属性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HH思️️无邪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值