简体   繁体   English

Swift,iOS15,UIKit,CollectionView header问题

[英]Swift, iOS15, UIKit, CollectionView header issue

I am testing iOS15 and some new functionalities of UIKit .我正在测试iOS15UIKit的一些新功能。 I've encountered some issues, not sure how to solve them.我遇到了一些问题,不确定如何解决。 I did not change that code .我没有更改该代码 This is just a piece of code that worked perfectly with the iOS 14, now after updating my target, it throws an error.这只是一段与 iOS 14 完美配合的代码,现在更新我的目标后,它会抛出错误。

Xcode crashes the moment when my custom header for the UICollectionView of type UICollectionElementKindSectionHeader is being returned for the dataSource . Xcode 在为dataSource返回类型为UICollectionElementKindSectionHeaderUICollectionView自定义 header时崩溃。 Here is my code:这是我的代码:

private func configureDataSource() {
      dataSource = UICollectionViewDiffableDataSource<Section, Follower>(collectionView: collectionView, cellProvider: { (collectionView, indexPath, followers) -> UICollectionViewCell? in
         let cell = collectionView.dequeueReusableCell(withReuseIdentifier: FollowerCell.reuseId, for: indexPath) as! FollowerCell
         cell.set(on: followers)
         return cell
      })
      
      dataSource.supplementaryViewProvider = { (collectionView, kind, indexPath) in
         let header = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader,
                                                                      withReuseIdentifier: FollowersCollectionHeaderView.reuseId,
                                                                      for: indexPath) as! FollowersCollectionHeaderView
         
         header.set(with: self.user)
         return header
      }
   }

The log says:日志说:

the view returned from -collectionView:viewForSupplementaryElementOfKind:atIndexPath: does not match the element kind it is being used for.从 -collectionView:viewForSupplementaryElementOfKind:atIndexPath: 返回的视图与它所使用的元素种类不匹配。 When asked for a view of element kind 'FollowersCollectionHeaderView' the data source dequeued a view registered for the element kind 'UICollectionElementKindSectionHeader'.当请求元素种类“FollowersCollectionHeaderView”的视图时,数据源使为元素种类“UICollectionElementKindSectionHeader”注册的视图出队。

I did cast UICollectionElementKindSectionHeader to FollowersCollectionHeaderView , therefore I am not sure what is the issue here.我确实将UICollectionElementKindSectionHeader 转换FollowersCollectionHeaderView ,因此我不确定这里的问题是什么。

I've watched WWDC21 what's new in UIKit but haven't seen any mentioning of any change for that particular code.我看过WWDC21 what's new in UIKit但没有看到任何提及该特定代码的任何更改。

Any suggestions, what to fix in that code?有什么建议,要在该代码中修复什么?

Here is the partial solution that I came up with.这是我想出的部分解决方案。 Apple recommends using object's ID as a reference for the collectionView cells. Apple 建议使用对象的 ID 作为 collectionView 单元格的参考。

enum Section { case main }


var dataSource: UICollectionViewDiffableDataSource<Section, Follower.ID>!

// MARK: - Collection View configurations
    fileprivate lazy var collectionView: UICollectionView = {
        let collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: UIHelper.createCompositionalLayout())
        collectionView.delegate = self
        collectionView.backgroundColor = .systemBackground
        collectionView.register(FollowersCollectionHeaderView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: FollowersCollectionHeaderView.reuseId)
        view.addSubview(collectionView)
        return collectionView
    }()
    
    fileprivate lazy var snapshot: NSDiffableDataSourceSnapshot<Section, Follower.ID> = {
        var snapshot = NSDiffableDataSourceSnapshot<Section, Follower.ID>()
        snapshot.appendSections([.main])
        let itemIdentifiers = followers.map { $0.id }
        snapshot.appendItems(itemIdentifiers, toSection: .main)
        dataSource.apply(snapshot, animatingDifferences: true)
        return snapshot
    }()
    
    fileprivate func updateData(with followers: [Follower]) {
        snapshot = NSDiffableDataSourceSnapshot<Section, Follower.ID>()
        snapshot.appendSections([.main])
        let itemIdentifiers = followers.map { $0.id }
        snapshot.appendItems(itemIdentifiers, toSection: .main)
        dataSource.apply(snapshot, animatingDifferences: true)
    }
    
    fileprivate func configureDataSource() {
        let cellRegistration = UICollectionView.CellRegistration<FollowerCell, Follower.ID> { [weak self]
            cell, indexPath, followerID in
            guard let self = self else { return }
            
            let followerArray = self.followers.filter { $0.id == followerID }
            
            if let follower = followerArray.first {
                cell.set(on: follower)
            }
        }
        
        dataSource = UICollectionViewDiffableDataSource<Section, Follower.ID>(collectionView: collectionView) {
            collectionView, indexPath, itemIdentifier in
            
            return collectionView.dequeueConfiguredReusableCell(using: cellRegistration,
                                                                for: indexPath,
                                                                item: itemIdentifier)
        }
        
        let headerRegistration = createSectionHeaderRegistration()
        dataSource.supplementaryViewProvider = { collectionView, elementKind, indexPath in
            return collectionView.dequeueConfiguredReusableSupplementary(using: headerRegistration, for: indexPath)
        }
    }
    
    fileprivate func createSectionHeaderRegistration() -> UICollectionView.SupplementaryRegistration<FollowersCollectionHeaderView> {
        return UICollectionView.SupplementaryRegistration<FollowersCollectionHeaderView>(
            elementKind: FollowersCollectionHeaderView.reuseId) { [weak self] supplementaryView, elementKind, indexPath in
            guard let self = self else { return }
            supplementaryView.set(with: self.user)
        }
    }

Use UICollectionView.elementKindSectionHeader instead of your created string使用UICollectionView.elementKindSectionHeader而不是您创建的字符串

override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
    
    guard let header = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "headerView", for: indexPath) as? TitleDetailsHeaderView else { return UICollectionReusableView() }

return header
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM