Swift UICollectionViewCompositionLayout&x27;s的粘头是干的
我正在尝试使用最新的UICollectionViewCompositionLayout来显示使用UICollectionViewDiffableDataSource的分页数据。我想在节上方显示一个粘性标题,即使在从网络加载下一页数据时,该标题也会始终位于顶部。。我注意到sticky header没有按预期工作,而是在后台下载数据并应用新快照时感觉不稳定。。我能够用苹果公司共享的示例应用程序重现这个问题 以下是重现问题的代码:Swift UICollectionViewCompositionLayout&x27;s的粘头是干的,swift,ios13,uicollectionviewcompositionallayout,nsdiffabledatasourcesnapshot,Swift,Ios13,Uicollectionviewcompositionallayout,Nsdiffabledatasourcesnapshot,我正在尝试使用最新的UICollectionViewCompositionLayout来显示使用UICollectionViewDiffableDataSource的分页数据。我想在节上方显示一个粘性标题,即使在从网络加载下一页数据时,该标题也会始终位于顶部。。我注意到sticky header没有按预期工作,而是在后台下载数据并应用新快照时感觉不稳定。。我能够用苹果公司共享的示例应用程序重现这个问题 以下是重现问题的代码: func layout() -> UICollectionVie
func layout() -> UICollectionViewLayout {
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
heightDimension: .fractionalHeight(1.0))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
heightDimension: .absolute(44))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
let section = NSCollectionLayoutSection(group: group)
section.interGroupSpacing = 5
section.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 10, bottom: 0, trailing: 10)
let sectionHeader = NSCollectionLayoutBoundarySupplementaryItem(
layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
heightDimension: .estimated(44)),
elementKind: sectionHeaderElementKind,
alignment: .top)
sectionHeader.pinToVisibleBounds = true
sectionHeader.zIndex = 2
section.boundarySupplementaryItems = [sectionHeader]
let layout = UICollectionViewCompositionalLayout(section: section)
return layout
}
上面的代码段提供了UICollectionViewCompositionalLayout,其中节标题固定在顶部的可见边界上
func setUpCollectionView() {
let collectionView = UICollectionView(frame: self.view.bounds, collectionViewLayout: layout())
collectionView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
collectionView.backgroundColor = .systemBackground
collectionView.register(ListCell.self, forCellWithReuseIdentifier: ListCell.reuseIdentifier)
collectionView.register(TitleSupplementaryView.self,
forSupplementaryViewOfKind: sectionHeaderElementKind,
withReuseIdentifier: TitleSupplementaryView.reuseIdentifier)
self.view.addSubview(collectionView)
collectionView.refreshControl = refreshControl
self.collectionView = collectionView
}
在上面的代码中,我将集合视图添加到视图控制器视图中
func configureDataSource() {
guard let collectionView = self.collectionView else {
return
}
dataSource = UICollectionViewDiffableDataSource<String, Int>(collectionView: collectionView) {
(collectionView: UICollectionView, indexPath: IndexPath, identifier: Int) -> UICollectionViewCell? in
// Get a cell of the desired kind.
guard let cell = collectionView.dequeueReusableCell(
withReuseIdentifier: ListCell.reuseIdentifier,
for: indexPath) as? ListCell else { fatalError("Cannot create new cell") }
// Populate the cell with our item description.
cell.label.text = "\(indexPath.section),\(indexPath.item)"
if self.canLoadNextPage(indexpath: indexPath) {
self.getNextPage()
}
// Return the cell.
return cell
}
dataSource?.supplementaryViewProvider = {
(collectionView: UICollectionView, kind: String, indexPath: IndexPath) -> UICollectionReusableView? in
// Get a supplementary view of the desired kind.
guard let headerFooter = collectionView.dequeueReusableSupplementaryView(
ofKind: kind,
withReuseIdentifier: TitleSupplementaryView.reuseIdentifier,
for: indexPath) as? TitleSupplementaryView else { fatalError("Cannot create new header") }
headerFooter.label.text = sectionHeader
headerFooter.backgroundColor = .lightGray
headerFooter.layer.borderColor = UIColor.black.cgColor
headerFooter.layer.borderWidth = 1.0
// Return the view.
return headerFooter
}
var snapshot = NSDiffableDataSourceSnapshot<String, Int>()
snapshot.appendSections([section])
items = Array(currentOffset..<currentOffset + 2*itemsPerPage)
currentOffset += 2*itemsPerPage
snapshot.appendItems(items)
serialQueue.async { [weak self] in
self?.dataSource?.apply(snapshot, animatingDifferences: true)
}
}
func configureDataSource(){
guard let collectionView=self.collectionView-else{
返回
}
dataSource=UICollectionViewDiffableDataSource(collectionView:collectionView){
(collectionView:UICollectionView,indexPath:indexPath,标识符:Int)->UICollectionViewCell?in
//获取所需类型的单元格。
guard let cell=collectionView.dequeueReusableCell(
withReuseIdentifier:ListCell.reuseIdentifier,
for:indexath)as?ListCell else{fatalError(“无法创建新单元格”)}
//用我们的项目描述填充单元格。
cell.label.text=“\(indexPath.section),\(indexPath.item)”
if self.canLoadNextPage(indexpath:indexpath){
self.getNextPage()
}
//把手机还给我。
返回单元
}
数据源?.supplementaryViewProvider={
(collectionView:UICollectionView,种类:字符串,indexPath:indexPath)->UICollectionReusableView?在
//获取所需类型的补充视图。
guard let headerFooter=collectionView.dequeueReusableSupplementaryView(
种类:种类,
使用reuseIdentifier:TitleSupplementaryView.reuseIdentifier,
for:indexPath)作为?TitleSupplementaryView else{fatalError(“无法创建新标头”)}
headerFooter.label.text=节头
headerFooter.backgroundColor=.lightGray
headerFooter.layer.borderColor=UIColor.black.cgColor
headerFooter.layer.borderWidth=1.0
//返回视图。
回程水头计
}
var snapshot=NSDiffableDataSourceSnapshot()
snapshot.appendSections([节])
items=数组(currentOffset..Bool{
保护(indexpath.item+5)>当前偏移量{
返回错误
}
返回真值
}
func getNextPage(){
fetchQueue.asyncAfter(截止日期:.now()+0.5){
var snapshot=NSDiffableDataSourceSnapshot()
snapshot.appendSections([节])
self.items.append(contentsOf:Array(self.currentOffset..我认为在没有动画的情况下应用快照不会发生此问题?我遇到了相同的问题..让我发疯!在没有动画的情况下应用快照修复了此问题..self?.dataSource?.apply(快照,动画差异:false)这太令人沮丧了。在iOS 14.2上也出现了同样的问题,现在我不得不将pinToVisibleBounds
设置为false
,并且在没有动画的情况下应用快照对meUICollectionViewCompositionalLayout和UICollectionViewDiffableDataSource都不起作用。虽然它们非常有用,但它们有很多问题,而且在iO上更糟S14。
func canLoadNextPage(indexpath: IndexPath) -> Bool {
guard (indexpath.item + 5) > currentOffset else {
return false
}
return true
}
func getNextPage() {
fetchQueue.asyncAfter(deadline: .now() + 0.5) {
var snapshot = NSDiffableDataSourceSnapshot<String, Int>()
snapshot.appendSections([section])
self.items.append(contentsOf: Array(self.currentOffset..<self.currentOffset + itemsPerPage))
snapshot.appendItems(self.items)
self.currentOffset += itemsPerPage
self.serialQueue.async { [weak self] in
self?.dataSource?.apply(snapshot, animatingDifferences: true)
}
}
}