I\'ve read a bunch of posts on adding header to UICollectionView. In an iOS 7+ app in Swift, I\'m trying to add a header with a UILabel in it whose height should adjust base
The idea is to have a template header instance in memory to calculate the desired height before creating the result header view. You should move your section header view to a separate .nib file, setup all autolayout constraints and instantiate the template in your viewDidLoad method like this:
class MyViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
@IBOutlet var collectionView : UICollectionView?
private var _templateHeader : MyHeaderView
override func viewDidLoad() {
super.viewDidLoad()
let nib = UINib(nibName: "HeaderView", bundle:nil)
self.collectionView?.registerNib(nib, forCellWithReuseIdentifier: "header_view_id")
_templateHeader = nib.instantiateWithOwner(nil, options:nil)[0] as! MyHeaderView
}
}
Then you will be able to calculate the header size (height in my example) in your flow layout delegate method:
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
_templateHeader.lblTitle.text = "some title here"
_templateHeader.lblDescription.text = "some long description"
_templateHeader.setNeedsUpdateConstraints();
_templateHeader.updateConstraintsIfNeeded()
_templateHeader.setNeedsLayout();
_templateHeader.layoutIfNeeded();
let computedSize = _templateHeader.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
return CGSizeMake(collectionView.bounds.size.width, computedSize.height);
}
And then create and return your regular header view as always, since you have already calculated its size in flow layout delegate method:
func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
switch kind {
case UICollectionElementKindSectionHeader:
let headerView = collectionView.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier: "header_view_id", forIndexPath: indexPath) as! MyHeaderView
headerView.lblTitle.text = "some title here"
headerView.lblDescription.text = "some long description"
headerView.setNeedsUpdateConstraints()
headerView.updateConstraintsIfNeeded()
headerView.setNeedsLayout()
headerView.layoutIfNeeded()
return headerView
default:
assert(false, "Unexpected kind")
}
}
Forgot to say about one important moment - your header view should have an autolayout constraint on its contentView to fit the collection view width (plus or minus the desired margins).