如何从代表的 collection 视图单元格中获取 indexPath 项目?

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

我有一个 collection 视图,其中有一个部分 header。在该部分 header 我添加了另一个 collection 视图,显示推荐的配置文件供用户关注,并且它水平滚动。

我无法从 ReuseableView(包含第二个 collection 视图)推送视图控制器,因此我创建了一个协议,该协议将包含可以为我推送视图控制器的功能。

当我点击个人资料(单元格)时,它会将我推送到我自己的个人资料。因为我无法获取另一个 collection 视图中的 indexPath.item

协议

protocol PeopleToFollowDelegate {
    func handleProfileTapped(for cell: FeedReusableView)
}

推送用户的功能

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

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


    }

总而言之,我只需要一种方法来获取 indexPath.item 以某种方式实现该功能。

编辑

这也是我在 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)

      }


您可以在 header 部分中使用 collection 视图委托 didSelectItem,并通过使用以下代码。

extension UIApplication {
 class func topVC(controller: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
    if let navigationController = controller as? UINavigationController {
      return topVC(controller: navigationController.visibleViewController)
    }
    if let tabController = controller as? UITabBarController {
      if let selected = tabController.selectedViewController {
        return topVC(controller: selected)
      }
    }
    if let presented = controller?.presentedViewController {
      return topVC(controller: presented)
    }
    return controller
  }
}

extension UIViewController {
  func pushVC(_ vc: UIViewController, animated: Bool = true) {
    navigationController?.pushViewController(vc, animated: animated)
  }
}

用例:UIApplication.topVC()?.pushVC(, animated: true)

按照@Abu Ul Hassan 的建议,您可以将 IndexPath 作为参数传递给您的协议函数,但在查看您的代码后,我发现您只需要选择索引,因此为简单起见,您可以通过以下方式执行此操作:

  1. 修改协议方法

     protocol PeopleToFollowDelegate {
         func handleProfileTapped(forIndex selectedIndex: Int)
     }
    
  2. 从用户的 collectionView 的 didSelect 委托调用委托函数

     func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
          peopleToFollowDelegate.handleProfileTapped(forIndex: indexPath.item) 
    
     }
    
  3. 然后像这样写handleProfileTapped函数:

    func handleProfileTapped(forIndex selectedIndex: Int) {
    
         let user = peopleToFollow[selectedIndex]
         let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
         let profileViewController = storyBoard.instantiateViewController(withIdentifier:"profileViewController") as? ProfileViewController
    
    
         profileViewController?.user = user
    
         // Then push to next controller
    }
    

您可以从

更改 didSelectRow 的实现
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

        profilesTapped()
}

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

        profilesTapped(user: peopleToFollow[indexPath.item])
}

这里是 profilesTapped 的实现

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

已编辑: 对于推送视图控制器,你应该这样做。如果我在使用 phone 时打错了内容,我深表歉意。

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)

}