簡體   English   中英

如何在tableview單元格內的collectionview單元格的按鈕單擊時獲取索引

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM