CollectionView 因无效 Header 而崩溃
Crash in CollectionView For Invalid Header
我想了解这个错误是什么意思?
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason:
'the view returned from -collectionView:viewForSupplementaryElementOfKind:atIndexPath: was not
retrieved by calling -dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath:
for element kind 'UICollectionElementKindSectionHeader' at index path <NSIndexPath: 0x8aeb905cf5be0ed2>
{length = 2, path = 0 - 0}; supplementary view:
<UICollectionReusableView: 0x7f9236dc4ff0; frame = (0 0; 0 0); layer = <CALayer: 0x600001018620>>'
我正在为 UICollectionView.I 使用自定义 header 我在加载视图后立即发生崩溃。甚至在调用 cellforrowatindexpath 之前,问题不在于自定义 header,而在于 return UICollectionReusableView()
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
if kind == UICollectionView.elementKindSectionHeader && indexPath.section == 2
{
return someCustomHeader
}
return UICollectionReusableView()
}
当您使用自定义 header 时,您必须先注册 header class。
collectionView.register(AppHeaderCollectionView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: AppHeaderCollectionView.headerIdentifier)
然后要使用 header 你必须这样做。
override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: AppHeaderCollectionView.headerIdentifier, for: indexPath) as! AppHeaderCollectionView
return header
}
您必须始终使用方法 dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath:
获取 header 部分,在调用它之前您还必须注册一个 header class。如果您只想显示第三部分的 header,您必须实施 collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int)
以隐藏不需要的 header,方法是给它们一个 .zero
大小(您不能简单地 return 一个 UICollectionReusableView
的实例用于不需要的 headers).
import UIKit
class CollectionViewController: UICollectionViewController {
private let headerId = "headerId"
override func viewDidLoad(){
super.viewDidLoad()
// Registers a header class
self.collectionView.register(YourClass.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: self.headerId) // Replace YourClass with the name of your header class
}
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
// This method must always call dequeueReusableSupplementaryView, even if section!=2
if kind == UICollectionView.elementKindSectionHeader{
return self.collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: self.headerId, for: indexPath)
}
return UICollectionReusableView()
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize{
// Shows only the header of the third section
return section == 2 ? desiredSize : .zero // Replace desiredSize with the size of the visible header
}
}
我想了解这个错误是什么意思?
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason:
'the view returned from -collectionView:viewForSupplementaryElementOfKind:atIndexPath: was not
retrieved by calling -dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath:
for element kind 'UICollectionElementKindSectionHeader' at index path <NSIndexPath: 0x8aeb905cf5be0ed2>
{length = 2, path = 0 - 0}; supplementary view:
<UICollectionReusableView: 0x7f9236dc4ff0; frame = (0 0; 0 0); layer = <CALayer: 0x600001018620>>'
我正在为 UICollectionView.I 使用自定义 header 我在加载视图后立即发生崩溃。甚至在调用 cellforrowatindexpath 之前,问题不在于自定义 header,而在于 return UICollectionReusableView()
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
if kind == UICollectionView.elementKindSectionHeader && indexPath.section == 2
{
return someCustomHeader
}
return UICollectionReusableView()
}
当您使用自定义 header 时,您必须先注册 header class。
collectionView.register(AppHeaderCollectionView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: AppHeaderCollectionView.headerIdentifier)
然后要使用 header 你必须这样做。
override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: AppHeaderCollectionView.headerIdentifier, for: indexPath) as! AppHeaderCollectionView
return header
}
您必须始终使用方法 dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath:
获取 header 部分,在调用它之前您还必须注册一个 header class。如果您只想显示第三部分的 header,您必须实施 collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int)
以隐藏不需要的 header,方法是给它们一个 .zero
大小(您不能简单地 return 一个 UICollectionReusableView
的实例用于不需要的 headers).
import UIKit
class CollectionViewController: UICollectionViewController {
private let headerId = "headerId"
override func viewDidLoad(){
super.viewDidLoad()
// Registers a header class
self.collectionView.register(YourClass.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: self.headerId) // Replace YourClass with the name of your header class
}
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
// This method must always call dequeueReusableSupplementaryView, even if section!=2
if kind == UICollectionView.elementKindSectionHeader{
return self.collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: self.headerId, for: indexPath)
}
return UICollectionReusableView()
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize{
// Shows only the header of the third section
return section == 2 ? desiredSize : .zero // Replace desiredSize with the size of the visible header
}
}