[英]How to get index on button click of collectionview cell which is inside tableview cell
我在 tableView 單元格中嵌入了一個 collectionView。 CollectionView 有多個項目,其中包含按鈕。 集合視圖數據源和委托正在 UITableViewCell 中設置。 為此,我必須根據該按鈕選擇執行一些操作,我需要知道 collectionView cell indexPath 和 tableView cell indexPath。 但無法弄清楚,如何實現這一點。 嘗試使用委托,但不知道如何在委托方法中獲取 collectionView 引用。
集合視圖單元格
protocol SelectedItemCellDelegate:class {
func deleteButtonDidTapped(_ cell: SelectedItemCell)
}
class SelectedItemCell: UICollectionViewCell {
class var identifier: String{
return String(describing: self)
}
class var nib: UINib{
return UINib(nibName: identifier, bundle: nil)
}
@IBOutlet weak var deleteButton: UIButton!
weak var delegate: SelectedItemCellDelegate?
override func awakeFromNib() {
super.awakeFromNib()
}
@IBAction func deleteAction(_ sender: Any) {
delegate?.deleteButtonDidTapped(self)
}
}
視圖控制器
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier:SelectedItemCell.identifier, for: indexPath) as! SelectedItemCell
cell.delegate = self
return cell
}
extension PrescriptionVC: SelectedItemCellDelegate
{
func deleteButtonDidTapped(_ cell: SelectedItemCell)
{
// Need tableview indexPath as well SelectedItemCell indexPath.
}
}
你需要兩個代表
protocol selectCollectionCellDelegate {
func selectCell(cell : UICollectionViewCell )
}
protocol selectTableCellDelegate {
func selectTableCell(cell : UITableViewCell , indexPath : IndexPath )
}
class YourCollectionViewCell : UICollectionViewCell {
var tvcDelegate : selectCollectionCellDelegate
@IBAction func deleteAction(_ sender: Any) {
tvcDelegate.selectCell(cell : self)
}
}
class YourTableViewCell : UITableViewCell , selectCollectionCellDelegate {
var vcDelegate : selectTableCellDelegate
func selectCell(cell : UICollectionViewCell ){
let indexPath : IndexPath = collectionView.indexPath(for: cell)!
delegate.selectTableCell(cell : self , indexPath : indexPath )
}
}
class YourviewController : UIViewController , selectTableCellDelegate{
func selectTableCell(cell : UITableViewCell , indexPath : IndexPath){
//indexPatn is IndexPath of collectionViewCell
let tableCellindexPath : IndexPath = tableView.indexPath(for: self)!
}
}
在 IBAction 方法中,您可以在 sender 參數中獲取觸發按鈕。 重寫您的委托方法以傳入按鈕和選定的集合視圖單元格:
協議 SelectedItemCellDelegate:class { func deleteButton(_ deleteButton: UIButton, tappedInCell cell: SelectedItemCell) }
重寫您的 deleteAction 以將發送者作為UIButton
類(或任何UIView
類)傳遞
@IBAction func deleteAction(_ sender: UIButton) {
delegate?. deleteButton(sender, tappedInCell: self)
}
然后你可以向 UICollectionView 和 UITableView 添加擴展,讓你使用按鈕的坐標找出包含按鈕的單元格:
extension UICollectionView {
func indexPathForCellContaining( view: UIView) -> IndexPath? {
let viewCenter = self.convert(view.center, from: view.superview)
return self.indexPathForItem(at: viewCenter)
}
}
或者對於表格視圖:
public extension UITableView {
/**
This method returns the indexPath of the cell that contains the specified view
- Parameter view: The view to find.
- Returns: The indexPath of the cell containing the view, or nil if it can't be found
*/
func indexPathForView(_ view: UIView) -> IndexPath? {
let center = view.center
//The center of the view is a better point to use, but we can only use it if the view has a superview
guard let superview = view.superview else {
//The view we were passed does not have a valid superview.
//Use the view's bounds.origin and convert from the view's coordinate system
let origin = self.convert(view.bounds.origin, from: view)
let indexPath = self.indexPathForRow(at: origin)
return indexPath
}
let viewCenter = self.convert(center, from: superview)
let indexPath = self.indexPathForRow(at: viewCenter)
return indexPath
}
}
由於您已經將集合視圖單元格傳遞給委托,您可以使用func indexPath(for cell: UICollectionViewCell)
來獲取 CollectionView 單元格的 indexPath。 如果你能得到一個指向表視圖的指針,你可以使用上面的表視圖擴展從表視圖中獲取按鈕的索引路徑。
為此,不鼓勵您在 Swift 中使用委托和查看數學。 使用簡單的回調閉包
在單元格中刪除與協議相關的代碼,聲明閉包並在按下按鈕時調用它
class SelectedItemCell: UICollectionViewCell {
class var identifier: String{
return String(describing: self)
}
class var nib: UINib{
return UINib(nibName: identifier, bundle: nil)
}
@IBOutlet weak var deleteButton: UIButton!
var callback : (() -> Void)?
@IBAction func deleteAction(_ sender: Any) {
callback?()
}
}
在控制器中設置閉包並處理回調,索引路徑被捕獲。
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier:SelectedItemCell.identifier, for: indexPath) as! SelectedItemCell
cell.callback = {
print("button pressed", indexPath)
}
return cell
}
如果可以插入、刪除或移動項目,僅捕獲indexPath
中的cellForItemAt
不起作用,因為索引路徑可以在不調用cellForItemAt
情況下cellForItemAt
。 在這種情況下,您必須在閉包中傳遞單元格並獲取實際索引路徑
var callback : ((UICollectionViewCell) -> Void)?
@IBAction func deleteAction(_ sender: Any) {
callback?(self)
}
和
cell.callback = { currentCell in
print("button pressed", collectionView.indexPath(for: currentCell)!
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.