4

I'm using viewForSupplementaryElementOfKind to generate a header in my Collection View.

The header (SectionHeader) is a Section Header accessory in Storyboard that simply just contains 1 outlet.

class SectionHeader: UICollectionReusableView {
    @IBOutlet weak var sectionHeaderlabel: UILabel!
}

Here's my implementation of viewForSupplementaryElementOfKind

func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind:
    String, at indexPath: IndexPath) -> UICollectionReusableView {

    print("SECTION TITLE (brand of bindings) --------> \(sectionTitle)")

    if let sectionHeader = allCollectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "bindingsID", for: indexPath) as? SectionHeader{
        sectionHeader.sectionHeaderlabel.text = "Select \(sectionTitle)"
        return sectionHeader
    }
    return UICollectionReusableView()

}

sectionTitle gets set via segue.

The problem is when this View Controller loads, the title reads "Select "

When I scroll the header off the screen, and then back on the screen, the title properly displays: "Select Burton Bindings"

I tested sectionTitle in viewWillAppear, and the correct data printed.

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    print("viewWillAppear ----- \(sectionTitle)")
}

(printed viewWillAppear ----- Burton Bindings)

I suppose my issue is due to the lifecycle of viewForSupplementaryElementOfKind, and when it is being called?

How can I get the section title to display when the VC loads, instead of having to scroll the header off and on the screen in order for it to display?

Joe
  • 3,772
  • 3
  • 33
  • 64

2 Answers2

0

I see two possible alternates (if I understood your use-case correctly first is preferable).

1) make available sectionTitle at view controller instantiation (ie. before view is loaded)

2) rebuild section layout right before appear (when your title is available) - this one much heavy

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    print("viewWillAppear ----- \(sectionTitle)")

    // as it is available here force rebuild sections
   self.collectionView.collectionViewLayout.invalidateLayout() 
}
Asperi
  • 228,894
  • 20
  • 464
  • 690
0

The issue here was viewForSupplementaryElementOfKind was being called before viewWillAppear. Within viewWillAppear, I was reloading the Collection View. All I had to do to properly display the section header title was updating it in viewWillAppear, after .reloadItems

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    // ---
    allCollectionView.reloadItems(at: allCollectionView.indexPathsForVisibleItems)

    // Access the SectionHeader and update the title now.
    let headerView = allCollectionView.visibleSupplementaryViews(ofKind: UICollectionView.elementKindSectionHeader)[0] as! SectionHeader
    headerView.sectionHeaderLabel.text = "Select \(sectionTitle)"

}

There is no text being set in viewForSupplementaryElementOfKind.

The trick here was to update the headerView sectionHeaderLabel text in viewWillAppear after the collectionView gets reloaded.

Joe
  • 3,772
  • 3
  • 33
  • 64