如何获取 UICollectionView Header 的 IndexPath?
Posted
技术标签:
【中文标题】如何获取 UICollectionView Header 的 IndexPath?【英文标题】:How to get IndexPath for UICollectionView Header? 【发布时间】:2020-01-02 08:30:14 【问题描述】:视图:页眉视图
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)
协议:HeaderCellDelegate
protocol HeaderCellDelegate: class
func expandSelectedHeader(_ header: UICollectionViewCell)
控制器: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)
我正在尝试在 headerView 中使用 clearButton,当点击按钮时,它会将自身(UIcollectionViewCell)发送到控制器。因此,一旦控制器接收到有关单元格的信息,我就可以使用collectionView.indexPath(for cell:UICollectionViewCell)
来获取点击按钮的标题的 indexPath。但是使用上面的代码,我只能得到nil
和print(indexPath)
。
我该如何解决这个问题??? 我提前感谢您的帮助。
【问题讨论】:
【参考方案1】:您的委托函数expandSelectedHeader()
不知道它的indexPath
,除非您将它传递给它。一种解决方法是在 HeaderCell
类中声明一个索引路径属性,并在创建补充视图时传递该值:
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)
还要稍微修改一下协议:
protocol HeaderCellDelegate: class
func expandSelectedHeader(_ header: UICollectionViewCell, indexPath: IndexPath?)
在创建视图时分配索引路径:
// ...
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
// ...
最后:
extension SomeController:HeaderCellDelegate
func expandSelectedHeader(_ header: UICollectionViewCell, indexPath: IndexPath)
print(indexPath)
【讨论】:
感谢您对 Maysam 的评论,所以我们不能对标题单元格做这样的事情吗? ***.com/a/44368931/11530917 重点是你的子类本质上并不知道它被分配到的索引路径。 这就是为什么我要在func expandSelectedHeader(_ header: UICollectionViewCell)
中使用let indexPath = collectionView.indexPath(for: header)
??
我猜它不适用于Supplementary View
,但我不确定。【参考方案2】:
而不是发送整个单元格然后获取索引路径。在协议中发送 IndexPath 并从中获取标头是一个好方法
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
现在在 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
【讨论】:
在哪里可以找到 didSelectSection?你是说 didSelectItemAt 吗?gesture.view
这是从哪里来的?
它的gestureRecognizer.view ...抱歉忘记更改
来自参数以上是关于如何获取 UICollectionView Header 的 IndexPath?的主要内容,如果未能解决你的问题,请参考以下文章
如何从子 UICollectionview 中获取 UITableView 的一部分
UICollectionView:如何在委托方法中设置特定项目后获取项目大小
如何在 UICollectionView 中获取选中的 CollectionViewCell?