私はカスタムレイアウトでUICollectionView
に取り組んでいます。 2日間で、UICollectionView
にヘッダーを追加する方法がわかりません。非常にシンプルなViewController(カスタムレイアウトのストーリーボードで作成)があります:
class ACollectionViewController: UICollectionViewController {
enum Identifiers: String {
case CellIdentifier = "Cell"
case HeaderIdentifier = "Header"
}
override func viewDidLoad() {
super.viewDidLoad()
self.collectionView.registerClass(UICollectionReusableView.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: Identifiers.HeaderIdentifier.rawValue)
}
// MARK: UICollectionViewDataSource
override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(Identifiers.CellIdentifier.rawValue, forIndexPath: indexPath) as Cell
cell.backgroundColor = UIColor.redColor()
return cell
}
override func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
println("ip = \(indexPath.item)")
var supplementaryView = collectionView.dequeueReusableCellWithReuseIdentifier(Identifiers.HeaderIdentifier.rawValue, forIndexPath: indexPath) as UICollectionReusableView
supplementaryView.backgroundColor = UIColor.blueColor()
return supplementaryView
}
そして、これが私のカスタムレイアウトです:
class ALayout: UICollectionViewLayout {
override func prepareLayout() {
super.prepareLayout()
}
override func collectionViewContentSize() -> CGSize {
return self.collectionView!.bounds.size
}
let itemWidth = 40
override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes! {
var attributes = UICollectionViewLayoutAttributes(forCellWithIndexPath: indexPath)
let x: Float = Float(10) * Float(indexPath.item)
let y: Float = Float(indexPath.item * itemWidth)
attributes.frame = CGRect(x: CGFloat(x), y: CGFloat(y), width: CGFloat(itemWidth), height: CGFloat(itemWidth))
return attributes
}
override func layoutAttributesForElementsInRect(rect: CGRect) -> [AnyObject]? {
var attributes = [UICollectionViewLayoutAttributes]()
let sectionsCount = self.collectionView!.dataSource!.numberOfSectionsInCollectionView!(self.collectionView!)
for section in 0..<sectionsCount {
/// add header
attributes.append(self.layoutAttributesForSupplementaryViewOfKind(UICollectionElementKindSectionHeader, atIndexPath: NSIndexPath(forItem: 0, inSection: section)))
let itemsCount = self.collectionView!.numberOfItemsInSection(section)
for item in 0..<itemsCount {
let indexPath = NSIndexPath(forItem: item, inSection: section)
attributes.append(self.layoutAttributesForItemAtIndexPath(indexPath))
}
}
return attributes
}
override func layoutAttributesForSupplementaryViewOfKind(elementKind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes! {
var attributes = UICollectionViewLayoutAttributes(forSupplementaryViewOfKind: elementKind, withIndexPath: indexPath)
attributes.frame = CGRect(x: 0, y: 0, width: 320, height: 50)
return attributes
}
}
問題は、セクションヘッダーを正しく追加する方法、このヘッダーのindexPathがどうあるべきかがわからないことです。ヘッダーが追加されているコードにコメントがあります。アプリはエラーで起動時にクラッシュします
2014-10-21 13:06:22.793 UICollectionViewLayout-Demo[3805:95924] *** Terminating app due to
uncaught exception 'NSInternalInconsistencyException', reason: 'could not dequeue a view of
kind: UICollectionElementKindCell with identifier Header - must register a nib or a class for
the identifier or connect a prototype cell in a storyboard'
これは、セルに追加しようとしているセクションヘッダーと同じindexPathがあるためですが、ヘッダーのindexPathはどうあるべきですか?それとも私はそれを完全に間違っているのでしょうか?
前もって感謝します。
使用しているためにクラッシュが発生しています
var supplementaryView = collectionView.dequeueReusableCellWithReuseIdentifier(Identifiers.HeaderIdentifier.rawValue, forIndexPath: indexPath) as UICollectionReusableView
ヘッダーとフッターをデキューしようとします(collectionView:viewForSupplementaryElementOfKind
)。に変更する
var supplementaryView = collectionView.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier:Identifiers.HeaderIdentifier.rawValue, forIndexPath: indexPath) as UICollectionReusableView
indexPathを調査できるように、クラッシュを取り除く必要があります。しかし、私のテストでは、indexPathは常に「0」です。
ヘッダーに間違った関数を使用しています。 Appleドキュメントのとおり、ヘッダーとフッターには次を使用します。
func dequeueReusableSupplementaryViewOfKind(_ elementKind: String,
withReuseIdentifier identifier: String,
forIndexPath indexPath: NSIndexPath!) -> AnyObject
代わりに:
var supplementaryView = collectionView.dequeueReusableCellWithReuseIdentifier(Identifiers.HeaderIdentifier.rawValue, forIndexPath: indexPath) as UICollectionReusableView
var supplementaryView = collectionView.dequeueReusableCellWithReuseIdentifier(Identifiers.HeaderIdentifier.rawValue, forIndexPath: indexPath) as UICollectionReusableView
の代わりに
する必要があります
let supplementaryView = collectionView.dequeueReusableSupplementaryViewOfKind(kind withReuseIdentifier:Identifiers.HeaderIdentifier.rawValue, forIndexPath:indexPath)