2020/9/11 突然在 Firebase Crashlytics 上接到為數不少的閃退錯誤訊息:
Fatal Exception: NSInternalInconsistencyException
the view returned from -collectionView:viewForSupplementaryElementOfKind:atIndexPath (UICollectionElementKindSectionHeader,<NSIndexPath: 0x850daa46ec075df5> {length = 2, path = 3 – 0}) was not retrieved by calling -dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath: or is nil (<UICollectionReusableView: 0x141920c10; frame = (0 0; 0 0); layer = <CALayer: 0x2823a5100>>)
奇怪的是在 9/11 以前一個閃退記錄都沒有,不知道是不是 Crashlytics team 有針對抓錯系統做了某些調整讓這個錯誤可以被抓出來。
稍微研究了一下發現是 UICollectionReusableView 搞的鬼,
在 collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) 裡必須要使用 collectionView.dequeueReusableSupplementaryView 來建立 UICollectionReusableView,
也就是你不能直接 return UICollectionReusableView()。
如果是遇到需要回傳空白的 collection reusable view,可以建立一個自訂的 EmptyCollectionReusableView:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class EmptyCollectionReusableView: UICollectionReusableView { | |
} |
記得 collection view 要註冊 EmptyCollectionReusableView:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
collectionView.register(EmptyCollectionReusableView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "empty") |
在需要空 header/footer 的地方回傳 EmptyCollectionReusableView:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
return collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "empty", for: indexPath) |