Search code examples
iosswiftuicollectionviewpushviewcontroller

How to grab indexPath item from a collection view cell for a delegate?


I have a collectionView that has a section header. In that section header I've added another collectionView that displays recommended profiles for users to follow, and it scrolls horizontal.

I cannot push view controllers from a ReuseableView ( that holds the second collection view), so I created a protocol that will hold a function that can push the view controller for me.

When I tap a profile (cell) it pushes me to my own profile. Because I cannot grab the indexPath.item that is in another collectionView.

Protocol

  • Here I create the protocol that holds the func HandleProfileTapped ,the cell named FeedReuseableView is the name of the sectionHeader that holds the second collection view.
protocol PeopleToFollowDelegate {
    func handleProfileTapped(for cell: FeedReusableView)
}

Function to push user

  • Right here is the function I created in the feed file, I will use this function in the delegate for the section header. However this is where my issues start.
 // Create function to push users to the correct profile when selected
    func handleProfileTapped(for header: FeedReusableView) {

        print("profile tapped, push user to the correct profile page")
       let header = FeedReusableView()

        //try to grab the indexpath item so the corrext data is pushed
        let user = header.peopleToFollow // ??? What goes here? I cannot grab index path

            let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)

           let profileViewController = storyBoard.instantiateViewController(withIdentifier: "profileViewController") as? ProfileViewController
            profileViewController?.user? = user


            self.navigationController?.pushViewController(profileViewController!, animated: true)

       }
  • This is where I get the biggest issue, peopleToFollow = [User]() is the recommended profiles users will see in the section header. IF the collection view was not in a section header, then I would easily grab the indexPath like this
// When profile is tapped, push user to userProfile
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

        let user = peopleToFollow[indexPath.item]
        let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
        let profileViewController = storyBoard.instantiateViewController(withIdentifier: "profileViewController") as? ProfileViewController


        profileViewController?.user = user

        // Then push to next controller ( profile)


    }

To sum it up, I just need a way to grab the indexPath.item somehow for that func.

Edit

Here is also were I use the function in the FeedReuseableView

var delegate: PeopleToFollowDelegate?


func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }

    // Return the number of profiles
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return peopleToFollow.count
    }

    //Display the recommended profiles
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "profilesCell", for: indexPath) as! PeopleToFollowCollectionCell

        cell.user = peopleToFollow[indexPath.item]

        return cell
    }

    // When profile is tapped, push user to userProfile
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

        profilesTapped()

    }

    @objc func profilesTapped() {
        delegate?.handleProfileTapped(for: self)

      }



Solution

  • you can change the implementation of didSelectRow from

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    
            profilesTapped()
    }
    

    to

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    
            profilesTapped(user: peopleToFollow[indexPath.item])
    }
    

    Here is the implementation of profilesTapped

    @objc func profilesTapped(user: User) {
        delegate?.handleProfileTapped(for: user)
    }
    

    Edited: For pushing view controller you should do this. Apologies if I typed something wrong as I am using my phone now.

    func handleProfileTapped(for user: User) {
        let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
    
        if let profileViewController = storyBoard.instantiateViewController(withIdentifier: "profileViewController") as? ProfileViewController {
        profileViewController.user = user
        self.navigationController?.pushViewController(profileViewController, animated: true)
    
    }