Reputation: 3241
I have a UICollectionView
, with header and footer enabled:
The height for the footer is set here:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
if isLoading {
return CGSize.zero
}
return CGSize(width: collectionView.bounds.size.width, height: 55)
}
...and I set both the header and footer here:
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
if kind == UICollectionView.elementKindSectionFooter {
let aFooterView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: footerViewReuseIdentifier, for: indexPath) as! CustomFooterView
self.footerView = aFooterView
self.footerView?.backgroundColor = UIColor.green
return aFooterView
} else {
let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "HeaderView", for: indexPath) as! CollectionViewHeader
return headerView
}
}
And register them here:
collectionView?.register(CollectionViewHeader.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "HeaderView")
collectionView?.register(UINib(nibName: "CustomFooterView", bundle: nil), forSupplementaryViewOfKind: UICollectionView.elementKindSectionFooter, withReuseIdentifier: footerViewReuseIdentifier)
When I set my collection view to use the default layout, I'm able to see both the header and the footer. When I set it to the below, custom layout, I only see the header, but NOT the footer, and am at a loss as to why that is:
class ColumnFlowLayout: UICollectionViewFlowLayout {
private let minColumnWidth: CGFloat = 300.0
private let cellHeight: CGFloat = 184.0
private var deletingIndexPaths = [IndexPath]()
private var insertingIndexPaths = [IndexPath]()
// MARK: Layout Overrides
/// - Tag: ColumnFlowExample
override func prepare() {
super.prepare()
guard let collectionView = collectionView else { return }
let availableWidth = collectionView.bounds.inset(by: collectionView.layoutMargins).width
let maxNumColumns = Int(availableWidth / minColumnWidth)
let cellWidth = (availableWidth / CGFloat(maxNumColumns)).rounded(.down)
self.itemSize = CGSize(width: cellWidth, height: cellHeight)
self.sectionInset = UIEdgeInsets(top: self.minimumInteritemSpacing, left: 0.0, bottom: 0.0, right: 0.0)
self.sectionInsetReference = .fromSafeArea
}
// MARK: Attributes for Updated Items
override func finalLayoutAttributesForDisappearingItem(at itemIndexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
guard let attributes = super.finalLayoutAttributesForDisappearingItem(at: itemIndexPath) else { return nil }
if !deletingIndexPaths.isEmpty {
if deletingIndexPaths.contains(itemIndexPath) {
attributes.transform = CGAffineTransform(scaleX: 0.5, y: 0.5)
attributes.alpha = 0.0
attributes.zIndex = 0
}
}
return attributes
}
override func initialLayoutAttributesForAppearingItem(at itemIndexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
guard let attributes = super.initialLayoutAttributesForAppearingItem(at: itemIndexPath) else { return nil }
if insertingIndexPaths.contains(itemIndexPath) {
attributes.transform = CGAffineTransform(scaleX: 0.5, y: 0.5)
attributes.alpha = 0.0
attributes.zIndex = 0
}
return attributes
}
// MARK: Updates
override func prepare(forCollectionViewUpdates updateItems: [UICollectionViewUpdateItem]) {
super.prepare(forCollectionViewUpdates: updateItems)
for update in updateItems {
switch update.updateAction {
case .delete:
guard let indexPath = update.indexPathBeforeUpdate else { return }
deletingIndexPaths.append(indexPath)
case .insert:
guard let indexPath = update.indexPathAfterUpdate else { return }
insertingIndexPaths.append(indexPath)
default:
break
}
}
}
override func finalizeCollectionViewUpdates() {
super.finalizeCollectionViewUpdates()
deletingIndexPaths.removeAll()
insertingIndexPaths.removeAll()
}
}
EDIT For some reason if I set
collectionView.collectionViewLayout = ColumnFlowLayout()
, the footer is nil, but if I don't set the layout to ColumnFlowLayout
then the footer is allocated properly.
EDIT 2 Can confirm that in this delegate method:
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
if kind == UICollectionView.elementKindSectionFooter {
let aFooterView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: footerViewReuseIdentifier, for: indexPath) as! CustomFooterView
self.footerView = aFooterView
self.footerView?.backgroundColor = UIColor.green
return aFooterView
} else {
let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "HeaderView", for: indexPath) as! CollectionViewHeader
return headerView
}
}
When I have:
collectionView.collectionViewLayout = ColumnFlowLayout()
,
the program never reaches
if kind == UICollectionView.elementKindSectionFooter
, but it DOES reach that if collectionView.collectionViewLayout = ColumnFlowLayout()
is commented out.
Upvotes: 2
Views: 988
Reputation: 3241
Figured it out; needed to manually set the footer height inside the ColumnFlowLayout
implementation like so:
self.footerReferenceSize = CGSize(width: w, height: h)
Upvotes: 1