【问题标题】:Crash in CollectionView For Invalid Header无效标题在 CollectionView 中崩溃
【发布时间】:2021-12-31 00:44:48
【问题描述】:

我想了解这个错误是什么意思?

 *** 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 使用自定义标题。一旦加载视图,我就会崩溃。甚至在调用 cellforrowatindexpath 之前,问题不在于自定义标头,而是与返回 UICollectionReusableView()

func collectionView(_ collectionView: UICollectionView,   viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
    
    if kind == UICollectionView.elementKindSectionHeader  && indexPath.section == 2      
    { 
     return someCustomHeader
    }
    
    return UICollectionReusableView()
}
    

【问题讨论】:

    标签: ios swift uicollectionview


    【解决方案1】:

    当您使用自定义标头时,您必须先注册标头类。

      collectionView.register(AppHeaderCollectionView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: AppHeaderCollectionView.headerIdentifier)
    

    然后为了使用标题,你必须这样做。

     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
        }
    

    【讨论】:

    • 对不起,问题不清楚。我对自定义标头没有问题。我遇到了 UICollectionReusableView() 的问题
    【解决方案2】:

    您必须始终使用方法dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath: 获取节标题,在调用它之前您还必须注册一个标题类。如果您只想显示第三部分的标题,您必须实现 collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) 以通过给它们一个 .zero 大小来隐藏不需要的标题(对于不需要的标题,您不能简单地返回 UICollectionReusableView 的实例)。

    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
        }
    }
    

    【讨论】:

    • 感谢您的回答。我实际上注册了它,自定义标题没有问题。问题在于返回默认 UICollectionReusableView()
    • @CRRavi 您无法返回 UICollectionReusableView()nil,因此您必须始终返回您的自定义标头,即使 section!=2 也是如此。然后您可以实现collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) 来隐藏不需要的标题,请参阅我的答案中的代码(您始终返回zero 大小,而不是在第三部分返回可见部分所需的大小)
    • @CRRavi 我还包括头类注册,但在我的回答中,我已经为您的问题插入了解决方案。
    • 将高度设置为 0 就可以了。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2021-01-13
    • 1970-01-01
    • 2013-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-13
    • 1970-01-01
    相关资源
    最近更新 更多