iosswiftuicollectionviewdelegatesuicollectionreusableview

Delegate Not Called in UICollectionReusableView


I have a single custom UICollectionReusableView as a UICollectionView header. Inside this view, I have two buttons. I have created a delegate method to perform the button actions however they are not being called.

I add my header in the UICollectionViewDataSource as follows;

func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
    let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: Identifier.exploreCollectionReusableView, for: indexPath) as! ExploreCollectionReusableView
    return headerView
}

I set up my protocol methods and add a delegate variable inside the custom header;

protocol SelectedDidSeeAll {
    func seeAllCategories()
    func seeAllItems()
}

var delegate: SelectedDidSeeAll?

I add the targets to the buttons;

seeAllCategoriesButton.addTarget(self, action: #selector(seeAllCategories), for: .touchUpInside)
seeAllItemsButton.addTarget(self, action: #selector(seeAllItems), for: .touchUpInside)

I set the delegate to be self in the UIViewController viewDidLoad()

exploreCollectionReusableView.delegate = self

I implement the @objc functions;

@objc func seeAllCategories() {
    delegate?.seeAllCategories()
}

@objc func seeAllItems() {
    delegate?.seeAllItems()
}

Lastly, I conform to the delegate method in the UIViewController;

extension ExploreViewController: SelectedDidSeeAll {

func seeAllCategories() {
    // Do Something
    print("something")
    }

func seeAllItems() {
    // Do Something
    print("something")
    }
}

Delegate Console Log

When printing the delegate I get;

Optional(<bidr.ExploreViewController: 0x7fd466e5d0b0>)

So I assume I have done everything necessary to implement the delegate method, however, clicking the buttons has no effect.


Solution

  • Instead of viewDidLoad(), set the delegate in collectionView(_: viewForSupplementaryElementOfKind: at:), i.e.

    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
        let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: Identifier.exploreCollectionReusableView, for: indexPath) as! ExploreCollectionReusableView
        headerView.delegate = self
        return headerView
    }
    

    In viewDidLoad(), the exploreCollectionReusableView might not be set.