Marian Petrisor
Marian Petrisor

Reputation: 302

Get IndexPath of CollectionViewCell outside of Cell

First of all I am a newbie in swift, so be gentle. I have a problem fetching the indexPath of the cell outside of the cell. I want to get that index path to a function and use it to send the content to another view. The image was created programatically in the cell, it has a tap gesture recogniser sending to this function (where "myIndex" is defined as an Int : var myIndex = 0):

// tap image to go at the indexpath of the user
func imageTapped(tapGestureRecognizer: UITapGestureRecognizer) {
   print("image tapped")

    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let secondViewController = storyboard.instantiateViewController(withIdentifier: "patientProfile") as! PatientProfileVC
    secondViewController.userID = posts[myIndex].userID
    secondViewController.patientName = posts[myIndex].author

    print("Passed data to the other view")

    self.show(secondViewController, sender: self)


}

I know that I could use didSelectItem at IndexPath where I also have the declaration of the myIndex but I have something that will be triggered from a segue there:

//standard functon for item selected
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

    //get the index of the cell
    myIndex = indexPath.row

    print("Cell is selected")

    //perform the segue
    self.performSegue(withIdentifier: "CommentsVC", sender: self)
    print(myIndex)

}

and my perform for segue looks like this:` override

func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    print("Segue Initiated")
    feed.navigationItem.title = nil

    //if segue.destination is CommentsFullVC{
        print("Comments segue initiated")
        let secondViewController = segue.destination as! CommentsFullVC
        secondViewController.questionData = posts[myIndex].postContent
        secondViewController.authorName = posts[myIndex].author
        secondViewController.date = posts[myIndex].normalDate
        secondViewController.profileImagePath = posts[myIndex].pathToImage
        secondViewController.typeOfClinic = posts[myIndex].clinic
        secondViewController.postID = posts[myIndex].postID
        secondViewController.followersForPost = posts[myIndex].followers

}

So my question is, how do I pass those 2 fields to the other view without using prepareForSegue? I am struggling with this for 20 hours now and still can not figure it out.

secondViewController.userID = posts[myIndex].userID
secondViewController.patientName = posts[myIndex].author

UPDATE: Got it to work thanks to Jose answer, now it looks like this... in case anybody has the same problem as I had.

 // tap image to go at the indexpath of the user
func imageTapped(tapGestureRecognizer: UITapGestureRecognizer) {
   print("image tapped")


    let pointInCollectionView = tapGestureRecognizer.location(in: collectionView)
    let indexPath = collectionView?.indexPathForItem(at: pointInCollectionView)
    print(indexPath!)

    // this one works - show segue
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let secondViewController = storyboard.instantiateViewController(withIdentifier: "patientProfile") as! PatientProfileVC
    secondViewController.userID = posts[(indexPath?.row)!].userID
    secondViewController.patientName = posts[(indexPath?.row)!].author

    print("Passed data to the other view")

    self.show(secondViewController, sender: self)


}

Upvotes: 3

Views: 2345

Answers (3)

Hugo Fortis
Hugo Fortis

Reputation: 429

I think this will be easy with a Delegate of the cell but its a little bit complicated.

The easy answer should be to store the index in the "tag" property of the imageView of the tapped image then extract from the gestureRecognizer You can add a tag where you create the imageView and the code where you recover the tag will look like this:

func imageTapped(tapGestureRecognizer: UITapGestureRecognizer) {
    print("image tapped")
    var myIndex = 0
    if let imageView = tapGestureRecognizer.view {
        myIndex = imageView.tag
    }

    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let secondViewController = storyboard.instantiateViewController(withIdentifier: "patientProfile") as! PatientProfileVC
    secondViewController.userID = posts[myIndex].userID
    secondViewController.patientName = posts[myIndex].author

    print("Passed data to the other view")

    self.show(secondViewController, sender: self)


}

Upvotes: 1

Hitesh
Hitesh

Reputation: 896

If your code write like below like then try this

collection view cell for row Method

cell.image = indexPath.row
let tap = UITapGestureRecognizer.init(target: self, action: #selector(imageTapped(_:)))
tap.accessibilityElements = [indexPath]
cell.image.addGestureRecognizer(tap)

Your function out side of collection view

func imageTapped (_ sender:UITapGestureRecognizer) {
     let index = sender.accessibilityElements?.first as! IndexPath   
     print(index.row)
     myIndex = index.row
}

Upvotes: 0

Jože Ws
Jože Ws

Reputation: 1814

Get the location of the tapGestureRecognizer in the collectionView and then the indexPath at the given location

let pointInCollectionView = tapGestureRecognizer.location(in: collectionView)
let indexPath = collectionView.indexPathForItem(at: pointInCollectionView)

Upvotes: 4

Related Questions