I'm making an iOS app in swift, and I'm trying to make a collectionView programmatically. I want to use my own subclass of UICollectionReusableView as a header for the CollectionView, because I need some buttons and a stretchable image in the header.
SupView is the UICollectionReusableView.
override func viewDidLoad() {
super.viewDidLoad()
let layout = UICollectionViewFlowLayout()
layout.headerReferenceSize = CGSizeMake(self.view.frame.width, 200)
someView = SupView(frame: CGRectMake(0, 0, view.frame.width, 200))
collectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
collectionView.delegate = self
collectionView.dataSource = self
collectionView.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: "Cell")
collectionView.registerClass(UICollectionReusableView.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "headerCell") // UICollectionReusableView
self.view.addSubview(collectionView)
}
I'm trying to insert the Supplementary View in viewForSupplementaryElementOfKind
, like this but I'm getting an error when trying to create the header:
func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
var reusableView : UICollectionReusableView? = nil
// Create header
if (kind == UICollectionElementKindSectionHeader) {
// Create Header
let headerView = collectionView.dequeueReusableSupplementaryViewOfKind(UICollectionElementKindSectionHeader, withReuseIdentifier: "headerCell", forIndexPath: indexPath) as! SupView
headerView.frame = CGRectMake(0, 0, view.frame.width, 200)
reusableView = headerView
}
return reusableView!
}
The error is in let headerView = ...
and says: "signal SIGABRT"
How should I initialize the headerview, so the I can input to my flowlayout?
maybe somewith with
collectionView.registerClass(UICollectionReusableView.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "headerCell")
but if I try to register the SupView-class it gives me error:
.../collectionViewPlay/ViewController.swift:32:24: Cannot invoke 'registerClass' with an argument list of type '(SupView!, forSupplementaryViewOfKind: String, withReuseIdentifier: String)'
Any Ideas?
EDIT:
The implementation of the subclass was requested:
import UIKit
class SupView: UICollectionReusableView {
override init(frame: CGRect) {
super.init(frame: frame)
self.myCustomInit()
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
self.myCustomInit()
}
func myCustomInit() {
print("hello there from SupView")
}
}
So I figured it out, with inspiration from Mohamad Farhand.
The problem was that I had to register the subclass itself with the collectionView, instead of UICollectionReusableView.self
, I used the instance of the subclass someView
.. So this solved my problem:
collectionView.registerClass(SupView.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader , withReuseIdentifier: "someRandonIdentifierString")
And how to initialize the view:
someView = collectionView.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier: "someRandonIdentifierString", forIndexPath: indexPath) as! SupView
Note that Swift 4.1 renames the ofKind: constant as UICollectionView.elementKindSectionHeader
.
you can do it like this:
// Setup Header
self.collectionView?.registerClass(CollectionCustomHeader.self, forSupplementaryViewOfKind: CustomeHeaderHeader, withReuseIdentifier: "customHeader")
also:
override func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
if kind == CustomeHeaderHeader {
let view = collectionView.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier: "parallaxHeader", forIndexPath: indexPath)
return view
}
Here is a Swift 3 & 4 answer I've used in a project
self.collectionView.register(LibraryHeaderNib.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader , withReuseIdentifier: "LibraryHeaderNib")
and inside viewForSupplementaryElementOfKind
let reusableView = self.collectionView!.dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "LibraryHeaderNib", for: indexPath) as! LibraryHeaderNib
return reusableView
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With