如何仅刷新CollectionView中的补充视图或头部视图而非全部数据?
嗨,这个问题我太熟了!不用每次都调用reloadData()刷整个列表,UICollectionView有好几种更精准的方式来单独刷新头部/补充视图,分情况给你说:
方法1:精准刷新指定的补充视图(iOS 15+ 推荐)
从iOS 15开始,系统提供了专门的方法来单独刷新补充视图,不用牵连到cell,非常高效:
- 刷新单个section的头部/尾部:
直接调用reloadSupplementaryViews(ofKind:at:),指定补充视图的类型和对应的indexPath(注意这里indexPath的item值不影响,因为补充视图是section级的,填0就行):// 刷新第0个section的头部视图 let targetIndexPath = IndexPath(section: 0, item: 0) collectionView?.reloadSupplementaryViews(ofKind: UICollectionElementKindSectionHeader, at: [targetIndexPath]) // 如果要刷新尾部视图,把kind换成UICollectionElementKindSectionFooter即可 // collectionView?.reloadSupplementaryViews(ofKind: UICollectionElementKindSectionFooter, at: [targetIndexPath]) - 刷新所有section的头部/尾部:
遍历所有section生成对应的indexPath数组,再批量刷新:guard let collectionView = collectionView else { return } // 生成所有section的indexPath let allHeaderIndexPaths = (0..<collectionView.numberOfSections).map { IndexPath(section: $0, item: 0) } // 批量刷新所有头部 collectionView.reloadSupplementaryViews(ofKind: UICollectionElementKindSectionHeader, at: allHeaderIndexPaths)
方法2:兼容iOS 15以下的方案
如果你的APP需要支持iOS 15之前的版本,可以用这两种方式:
- 方式A:利用批量更新触发刷新
调用performBatchUpdates,即使闭包里什么都不写,系统也会重新布局补充视图,间接实现刷新:
这种方式会刷新当前所有可见的补充视图,比collectionView?.performBatchUpdates({ // 这里不需要写任何代码,空闭包即可 }, completion: nil)reloadData()轻量很多。 - 方式B:直接获取视图并更新UI
如果你能拿到对应补充视图的引用,可以直接更新它的UI,这是最高效的方式:
这种方式完全不会触发系统的布局刷新,直接修改视图内容,但前提是你已经更新了数据源里的对应数据,并且视图是当前可见的。// 假设你的自定义头部是CustomHeaderView if let headerView = collectionView?.supplementaryView(forElementKind: UICollectionElementKindSectionHeader, at: IndexPath(section: 0, item: 0)) as? CustomHeaderView { // 直接调用自定义的更新方法,传入新数据 headerView.updateWithData(newHeaderData) }
注意事项
- 不管用哪种方法,都要确保你的数据源已经更新,不然刷新后还是旧数据。
- 如果是自定义的补充视图,要在
collectionView(_:viewForSupplementaryElementOfKind:at:)方法里正确根据数据源配置UI,这样系统刷新时才能显示新内容。
内容的提问来源于stack exchange,提问作者Alvin123
相关产品推荐
相关产品推荐

