如何在UICollectionView两单元格间随机插入不替换原内容的广告单元格
UICollectionView 独立广告单元格随机插入实现方案
核心逻辑是完全不修改原有业务数据源,将广告作为独立条目在渲染层单独插入,既不会替换原有内容,也不会侵入业务逻辑,最终效果参考下图:
具体实现步骤
- 拆分独立维护的两类数据源
不要把广告数据直接塞进原有业务内容的数组里,单独维护两个互不干扰的数据集:- 业务数据源:存所有原有信息流内容,全程不做任何增删改,和广告逻辑完全隔离,分页、筛选、刷新等原有业务逻辑照常运行
- 广告数据集:存拉取到的广告模型,同时单独维护一个集合类型变量,记录所有广告要插入的位置索引
- 生成合规的随机插入位置
随机生成位置时要避开体验问题和逻辑bug,遵守几个基础规则:- 非特殊需求不要把广告插在第0位,避免用户进页面第一眼就看到广告
- 两个广告之间至少保留3-5个业务内容的间隔,不要出现广告连排
- 插入位置不能超过业务数据总长度,避免数组越界
参考实现代码(Swift):
// 配置项:要插入的广告数量、广告间最小内容间隔 let targetAdCount = 3 let minContentGapBetweenAds = 4 var insertPositions = Set<Int>() // 循环生成符合间隔要求的随机位置 while insertPositions.count < min(targetAdCount, adList.count) { // 随机范围选1到业务数据总数-1,保证广告插在两个原有单元格之间 let randomPos = Int.random(in: 1..<businessDataArray.count) // 校验新位置和已有广告位的间隔是否达标 let meetGapRequirement = insertPositions.allSatisfy { abs($0 - randomPos) >= minContentGapBetweenAds } if meetGapRequirement { insertPositions.insert(randomPos) } } - 组装CollectionView专用的渲染数组
按顺序遍历原有业务数据,每往渲染数组里加1条业务数据,就检查当前遍历到的业务序号是不是在广告插入位置集合里——如果是,就按顺序取1条广告数据追加到渲染数组里,直到所有业务数据和待插入广告都处理完。
注意:插入广告后渲染数组的索引和原有业务数组的索引会有偏移,后续取业务数据时不要直接用CollectionView的indexPath.item去取业务数组的内容,要根据当前位置之前插了多少条广告做偏移计算。 - 区分处理两类单元格的渲染和交互
- 给业务单元格、广告单元格注册不同的复用ID
cellForItemAt回调里,先判断当前渲染数组对应位置的模型类型:是业务模型就走业务Cell的渲染逻辑,是广告模型就走广告Cell的渲染逻辑- 所有涉及点击跳转、尺寸计算、曝光埋点、删除移动的CollectionView代理方法,都先判断当前项的类型,分别走广告和业务的独立逻辑,不要混写
常见避坑点
- 下拉刷新、上拉加载更多之后,要重新计算广告插入位置,不要复用旧位置,避免广告扎堆、越界
- 如果广告拉取失败或者数量不足,直接跳过对应位置的广告插入即可,不要留空白占位
- 不要修改原有业务模型的字段来兼容广告逻辑,广告和业务模型完全分开定义,后续维护成本会低很多
内容的提问来源于stack exchange,提问作者JuFa512
相关产品推荐
相关产品推荐

