如何使用自定义 UICollectionReusableView 作为集合视图的部分标题?
Posted
技术标签:
【中文标题】如何使用自定义 UICollectionReusableView 作为集合视图的部分标题?【英文标题】:How to use custom UICollectionReusableView as section header of collection view? 【发布时间】:2020-04-05 18:11:13 【问题描述】:我已经发疯了好几个小时,因为我无法解决这个问题。
我有一个集合视图,它可以有不同的部分和不同的编号。在每个项目。对于每个部分,我需要使用不同类型的部分标题。所以为此,我将使用UICollectionReusableView
。但是我似乎无法通过UINib
注册来成功使用UICollectionReusableView
的自定义子类。
当我将可重用视图向下转换到我的子类时,会发生崩溃。喜欢:
let friendHeader = collectionView.dequeueReusableSupplementaryView(ofKind: kind,
withReuseIdentifier: "FriendHeaderView",
for: indexPath) as! FriendHeaderView
下面是sn-p的代码:
class ViewController: UIViewController
@IBOutlet weak var collectionView: UICollectionView!
private let viewModel = ProfileViewModel()
override func viewDidLoad()
super.viewDidLoad()
collectionView.dataSource = self
collectionView.delegate = self
// more code
collectionView.register(UINib(nibName: "FriendHeaderView", bundle: nil),
forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader,
withReuseIdentifier: "FriendHeaderView")
现在是数据源实现:
extension ViewController: UICollectionViewDataSource
func numberOfSections(in collectionView: UICollectionView) -> Int
// valid implementation
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
// valid implementation
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
// valid implementation
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView
switch kind
case UICollectionView.elementKindSectionHeader:
let friendHeader = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "FriendHeaderView", for: indexPath) as! FriendHeaderView
// *** Crash happens here *** //
return friendHeader
default:
assert(false, "Invalid element type")
而且我不知道为什么还需要实现collectionView(_:layout:referenceSizeForHeaderInSection:)
。所以这里是:
extension ViewController: UICollectionViewDelegateFlowLayout
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize
let size = CGSize(width: collectionView.bounds.width, height: 100)
return size
好的,现在进入正题:上面提到的崩溃不会发生 如果我不使用
as!
运营商的话。好吧,如果我使用部分 来自故事板的标题而不是UINib
注册,有 没有崩溃。
如果我需要多种类型的标题,那么我也不能使用情节提要方法或不使用向下转换方法,因为我需要将数据提供给这些标题。
如何使用从界面构建器构建的多个类型标题?
我已经根据上面所说的内容创建了demo project。如果有人有兴趣,请检查一下。
【问题讨论】:
【参考方案1】:一旦您在 Xib 文件中分配了正确的类和标识符,它就可以正常工作而不会崩溃。
【讨论】:
太棒了。其实就是这样。但我认为它需要为将来遇到同样问题的读者提供详细的答案。为此,我正在添加另一个答案。【参考方案2】:好吧,经过更多调查和@good4pc 在接受的答案中的输入(实际上我在查看答案之前自己发现了这一点)似乎问题实际上是由于 Xcode 的一些不需要的问题而发生的。
当我们使用.xib
创建任何视图(最好是UITableViewCell
或UICollectionViewCell
)时,会在身份检查器中自动为.xib
提供类身份。但UICollectionReusableView
的情况并非如此。请参阅下面随附的屏幕截图以便于理解。
这是UICollectionViewCell
的子类.xib
:
这是一个UICollectionReusableView
的子类.xib
:
所以关键是提供
.xib
文件的类标识 由属性检查器完成。
【讨论】:
以上是关于如何使用自定义 UICollectionReusableView 作为集合视图的部分标题?的主要内容,如果未能解决你的问题,请参考以下文章