How to get index on button click of collectionview cell which is inside tableview cell












1














I have a collectionView embedded in tableView cell. CollectionView has multiple items, which contains button. Collection View datasource and delegates are getting set in UITableViewCell. I have to perform some action based on that button selection for that, I need to know collectionView cell indexPath and tableView cell indexPath. But not able to figure out, how to achieve this. Tried using delegates, but don't know how to get collectionView reference in delegate method.



CollectionView Cell



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)
}
}


ViewController



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.
}
}









share|improve this question



























    1














    I have a collectionView embedded in tableView cell. CollectionView has multiple items, which contains button. Collection View datasource and delegates are getting set in UITableViewCell. I have to perform some action based on that button selection for that, I need to know collectionView cell indexPath and tableView cell indexPath. But not able to figure out, how to achieve this. Tried using delegates, but don't know how to get collectionView reference in delegate method.



    CollectionView Cell



    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)
    }
    }


    ViewController



    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.
    }
    }









    share|improve this question

























      1












      1








      1







      I have a collectionView embedded in tableView cell. CollectionView has multiple items, which contains button. Collection View datasource and delegates are getting set in UITableViewCell. I have to perform some action based on that button selection for that, I need to know collectionView cell indexPath and tableView cell indexPath. But not able to figure out, how to achieve this. Tried using delegates, but don't know how to get collectionView reference in delegate method.



      CollectionView Cell



      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)
      }
      }


      ViewController



      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.
      }
      }









      share|improve this question













      I have a collectionView embedded in tableView cell. CollectionView has multiple items, which contains button. Collection View datasource and delegates are getting set in UITableViewCell. I have to perform some action based on that button selection for that, I need to know collectionView cell indexPath and tableView cell indexPath. But not able to figure out, how to achieve this. Tried using delegates, but don't know how to get collectionView reference in delegate method.



      CollectionView Cell



      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)
      }
      }


      ViewController



      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.
      }
      }






      ios swift uitableview uicollectionview






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 22 at 18:22









      Xcoder

      517




      517
























          3 Answers
          3






          active

          oldest

          votes


















          0














          You are discouraged from using delegates and view math in Swift for this purpose. Use a simple callback closure



          In the cell delete the code related to the protocol, declare the closure and call it when a button is pressed



          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?()
          }
          }


          In the controller set the closure and handle the callback, the index path is captured.



          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
          }





          share|improve this answer































            2














            You need two delegates



            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)!
            }

            }





            share|improve this answer































              1














              In an IBAction method you can get the triggering button in the sender parameter. Rewrite your delegate method to pass in the button and the selected collection view cell:



              protocol SelectedItemCellDelegate:class {
              func deleteButton(_ deleteButton: UIButton, tappedInCell cell: SelectedItemCell)
              }



              Rewrite your deleteAction to pass sender as UIButton class (or any UIView class)



              @IBAction func deleteAction(_ sender: UIButton) {
              delegate?. deleteButton(sender, tappedInCell: self)
              }


              Then you can add extensions to both UICollectionView and UITableView that let you figure out the cell that contains the button using the button's coordinates:



              extension UICollectionView {
              func indexPathForCellContaining( view: UIView) -> IndexPath? {
              let viewCenter = self.convert(view.center, from: view.superview)
              return self.indexPathForItem(at: viewCenter)
              }
              }


              Or for table views:



              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
              }
              }


              Since you already pass the collection view cell to the delegate you can use func indexPath(for cell: UICollectionViewCell) to get the indexPath for the CollectionView cell. If you can get a pointer to the table view you can use the above table view extension to get the index path of the button from the table view.






              share|improve this answer





















              • I have solved it using tags, but it looks much cleaner and concrete. I'll accept it after testing. Thanks.
                – Xcoder
                Nov 22 at 21:28











              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53436418%2fhow-to-get-index-on-button-click-of-collectionview-cell-which-is-inside-tablevie%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              3 Answers
              3






              active

              oldest

              votes








              3 Answers
              3






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              0














              You are discouraged from using delegates and view math in Swift for this purpose. Use a simple callback closure



              In the cell delete the code related to the protocol, declare the closure and call it when a button is pressed



              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?()
              }
              }


              In the controller set the closure and handle the callback, the index path is captured.



              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
              }





              share|improve this answer




























                0














                You are discouraged from using delegates and view math in Swift for this purpose. Use a simple callback closure



                In the cell delete the code related to the protocol, declare the closure and call it when a button is pressed



                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?()
                }
                }


                In the controller set the closure and handle the callback, the index path is captured.



                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
                }





                share|improve this answer


























                  0












                  0








                  0






                  You are discouraged from using delegates and view math in Swift for this purpose. Use a simple callback closure



                  In the cell delete the code related to the protocol, declare the closure and call it when a button is pressed



                  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?()
                  }
                  }


                  In the controller set the closure and handle the callback, the index path is captured.



                  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
                  }





                  share|improve this answer














                  You are discouraged from using delegates and view math in Swift for this purpose. Use a simple callback closure



                  In the cell delete the code related to the protocol, declare the closure and call it when a button is pressed



                  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?()
                  }
                  }


                  In the controller set the closure and handle the callback, the index path is captured.



                  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
                  }






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Nov 23 at 9:08

























                  answered Nov 23 at 9:03









                  vadian

                  142k13151168




                  142k13151168

























                      2














                      You need two delegates



                      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)!
                      }

                      }





                      share|improve this answer




























                        2














                        You need two delegates



                        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)!
                        }

                        }





                        share|improve this answer


























                          2












                          2








                          2






                          You need two delegates



                          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)!
                          }

                          }





                          share|improve this answer














                          You need two delegates



                          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)!
                          }

                          }






                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited Nov 22 at 20:58









                          Paulw11

                          66.8k1081101




                          66.8k1081101










                          answered Nov 22 at 20:42









                          Ammar

                          1678




                          1678























                              1














                              In an IBAction method you can get the triggering button in the sender parameter. Rewrite your delegate method to pass in the button and the selected collection view cell:



                              protocol SelectedItemCellDelegate:class {
                              func deleteButton(_ deleteButton: UIButton, tappedInCell cell: SelectedItemCell)
                              }



                              Rewrite your deleteAction to pass sender as UIButton class (or any UIView class)



                              @IBAction func deleteAction(_ sender: UIButton) {
                              delegate?. deleteButton(sender, tappedInCell: self)
                              }


                              Then you can add extensions to both UICollectionView and UITableView that let you figure out the cell that contains the button using the button's coordinates:



                              extension UICollectionView {
                              func indexPathForCellContaining( view: UIView) -> IndexPath? {
                              let viewCenter = self.convert(view.center, from: view.superview)
                              return self.indexPathForItem(at: viewCenter)
                              }
                              }


                              Or for table views:



                              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
                              }
                              }


                              Since you already pass the collection view cell to the delegate you can use func indexPath(for cell: UICollectionViewCell) to get the indexPath for the CollectionView cell. If you can get a pointer to the table view you can use the above table view extension to get the index path of the button from the table view.






                              share|improve this answer





















                              • I have solved it using tags, but it looks much cleaner and concrete. I'll accept it after testing. Thanks.
                                – Xcoder
                                Nov 22 at 21:28
















                              1














                              In an IBAction method you can get the triggering button in the sender parameter. Rewrite your delegate method to pass in the button and the selected collection view cell:



                              protocol SelectedItemCellDelegate:class {
                              func deleteButton(_ deleteButton: UIButton, tappedInCell cell: SelectedItemCell)
                              }



                              Rewrite your deleteAction to pass sender as UIButton class (or any UIView class)



                              @IBAction func deleteAction(_ sender: UIButton) {
                              delegate?. deleteButton(sender, tappedInCell: self)
                              }


                              Then you can add extensions to both UICollectionView and UITableView that let you figure out the cell that contains the button using the button's coordinates:



                              extension UICollectionView {
                              func indexPathForCellContaining( view: UIView) -> IndexPath? {
                              let viewCenter = self.convert(view.center, from: view.superview)
                              return self.indexPathForItem(at: viewCenter)
                              }
                              }


                              Or for table views:



                              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
                              }
                              }


                              Since you already pass the collection view cell to the delegate you can use func indexPath(for cell: UICollectionViewCell) to get the indexPath for the CollectionView cell. If you can get a pointer to the table view you can use the above table view extension to get the index path of the button from the table view.






                              share|improve this answer





















                              • I have solved it using tags, but it looks much cleaner and concrete. I'll accept it after testing. Thanks.
                                – Xcoder
                                Nov 22 at 21:28














                              1












                              1








                              1






                              In an IBAction method you can get the triggering button in the sender parameter. Rewrite your delegate method to pass in the button and the selected collection view cell:



                              protocol SelectedItemCellDelegate:class {
                              func deleteButton(_ deleteButton: UIButton, tappedInCell cell: SelectedItemCell)
                              }



                              Rewrite your deleteAction to pass sender as UIButton class (or any UIView class)



                              @IBAction func deleteAction(_ sender: UIButton) {
                              delegate?. deleteButton(sender, tappedInCell: self)
                              }


                              Then you can add extensions to both UICollectionView and UITableView that let you figure out the cell that contains the button using the button's coordinates:



                              extension UICollectionView {
                              func indexPathForCellContaining( view: UIView) -> IndexPath? {
                              let viewCenter = self.convert(view.center, from: view.superview)
                              return self.indexPathForItem(at: viewCenter)
                              }
                              }


                              Or for table views:



                              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
                              }
                              }


                              Since you already pass the collection view cell to the delegate you can use func indexPath(for cell: UICollectionViewCell) to get the indexPath for the CollectionView cell. If you can get a pointer to the table view you can use the above table view extension to get the index path of the button from the table view.






                              share|improve this answer












                              In an IBAction method you can get the triggering button in the sender parameter. Rewrite your delegate method to pass in the button and the selected collection view cell:



                              protocol SelectedItemCellDelegate:class {
                              func deleteButton(_ deleteButton: UIButton, tappedInCell cell: SelectedItemCell)
                              }



                              Rewrite your deleteAction to pass sender as UIButton class (or any UIView class)



                              @IBAction func deleteAction(_ sender: UIButton) {
                              delegate?. deleteButton(sender, tappedInCell: self)
                              }


                              Then you can add extensions to both UICollectionView and UITableView that let you figure out the cell that contains the button using the button's coordinates:



                              extension UICollectionView {
                              func indexPathForCellContaining( view: UIView) -> IndexPath? {
                              let viewCenter = self.convert(view.center, from: view.superview)
                              return self.indexPathForItem(at: viewCenter)
                              }
                              }


                              Or for table views:



                              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
                              }
                              }


                              Since you already pass the collection view cell to the delegate you can use func indexPath(for cell: UICollectionViewCell) to get the indexPath for the CollectionView cell. If you can get a pointer to the table view you can use the above table view extension to get the index path of the button from the table view.







                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered Nov 22 at 20:12









                              Duncan C

                              91.8k13114195




                              91.8k13114195












                              • I have solved it using tags, but it looks much cleaner and concrete. I'll accept it after testing. Thanks.
                                – Xcoder
                                Nov 22 at 21:28


















                              • I have solved it using tags, but it looks much cleaner and concrete. I'll accept it after testing. Thanks.
                                – Xcoder
                                Nov 22 at 21:28
















                              I have solved it using tags, but it looks much cleaner and concrete. I'll accept it after testing. Thanks.
                              – Xcoder
                              Nov 22 at 21:28




                              I have solved it using tags, but it looks much cleaner and concrete. I'll accept it after testing. Thanks.
                              – Xcoder
                              Nov 22 at 21:28


















                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.





                              Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                              Please pay close attention to the following guidance:


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53436418%2fhow-to-get-index-on-button-click-of-collectionview-cell-which-is-inside-tablevie%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              Trompette piccolo

                              Slow SSRS Report in dynamic grouping and multiple parameters

                              Simon Yates (cyclisme)