Reputation: 478
View: HeaderView
class HeaderCell: UICollectionViewCell {
//MARK: - Properties
....
lazy var clearButton: UIButton = {
let bt = UIButton(type: .custom)
bt.backgroundColor = .clear
bt.addTarget(self, action: #selector(handleClearButton(button:)), for: .touchUpInside)
return bt
}()
weak var delegate: HeaderCellDelegate?
//MARK: - Init
required init?(coder aDecoder: NSCoder) {
return nil
}
override init(frame: CGRect) {
super.init(frame: frame)
configureCell()
addViews()
setConstraints()
}
....
//MARK: - Handlers
@objc func handleClearButton(button: UIButton) {
delegate?.expandSelectedHeader(self)
}
Protocol: HeaderCellDelegate
protocol HeaderCellDelegate: class {
func expandSelectedHeader(_ header: UICollectionViewCell)
}
Controller: SomeController
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
switch kind {
case UICollectionView.elementKindSectionHeader:
let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: reuseIdentifierForHeader, for: indexPath) as! HeaderCell
header.toMenuControllerDelegate = self
return header
case UICollectionView.elementKindSectionFooter:
let footer = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: reuseIdentifierForFooter, for: indexPath) as! MenuFooterCell
return footer
default:
return UICollectionReusableView()
}
}
extension SomeController:HeaderCellDelegate {
func expandSelectedHeader(_ header: UICollectionViewCell) {
let indexPath = collectionView.indexPath(for: header)
print(indexPath)
}
}
I am trying to using the clearButton inside headerView that when the button is tapped it will send itself(UIcollectionViewCell) to the controller. So once the controller receives information about the cell, I can use collectionView.indexPath(for cell:UICollectionViewCell)
to get the indexPath of header in which the button is tapped. But with the code above, I am only getting nil
for print(indexPath)
.
How can I go about the problem??? I appreciate your help in advance.
Upvotes: 0
Views: 882
Reputation: 14397
Instead of sending whole cell and then get index path. Send IndexPath in protocol and get header from that is a good approach
override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
switch kind {
case UICollectionElementKindSectionHeader:
let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "header", for: indexPath) as! HeaderCollectionReusableView
let gestureRecognizer: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(didSelectSection(gesture:)))
headerView.addGestureRecognizer(gestureRecognizer)
return headerView
}
}
Now in didSelectSection :
@objc func didSelectSection(_ gestureRecognizer: UITapGestureRecognizer) {
let indexPaths = self.collectionView?.indexPathsForVisibleSupplementaryElements(ofKind: UICollectionElementKindSectionHeader)
for indexPath in indexPaths! {
if (gestureRecognizer.view as! HeaderCollectionReusableView) == collectionView?.supplementaryView(forElementKind: UICollectionElementKindSectionHeader, at: indexPath){
print("found at : \(indexPath)")
break
}
}
}
Upvotes: 0
Reputation: 7367
Your delegate function, expandSelectedHeader()
does not know about its indexPath
unless you pass it to. A workaround is you declare a index path property within your HeaderCell
class and pass the value when you are creating the supplementary view:
class HeaderCell: UICollectionViewCell {
//MARK: - Properties
var indexPath: IndexPath?
// rest of the code
}
//MARK: - Handlers
@objc func handleClearButton(button: UIButton) {
delegate?.expandSelectedHeader(self, indexPath: self.indexPath)
}
Also change the protocol a bit:
protocol HeaderCellDelegate: class {
func expandSelectedHeader(_ header: UICollectionViewCell, indexPath: IndexPath?)
}
When you are creating the view assign the index path:
// ...
let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: reuseIdentifierForHeader, for: indexPath) as! HeaderCell
// I'd suggest do not force down case the view as HeaderCell, use if..let
header.toMenuControllerDelegate = self
header.indexPath = indexPath
// ...
Finally:
extension SomeController:HeaderCellDelegate {
func expandSelectedHeader(_ header: UICollectionViewCell, indexPath: IndexPath) {
print(indexPath)
}
}
Upvotes: 1