如何从委托的收集视图单元格中获取indexPath项?

时间:2019-09-26 02:18:14

标签: ios swift uicollectionview pushviewcontroller

我有一个带有节标题的collectionView。在该部分的标题中,我添加了另一个collectionView,其中显示了供用户遵循的推荐配置文件,并且它水平滚动。

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

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

协议

  • 在这里,我创建一个保存功能HandleProfileTapped的协议,名为FeedReuseableView的单元格是保存第二个集合视图的sectionHeader的名称。
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)

       }
  • 这是我遇到的最大问题,peopleToFollow = [User]()是用户在节标题中看到的推荐配置文件。 如果集合视图不在节标题中,那么我会很容易地像这样抓取indexPath
// 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)


    }

总结起来,我只需要一种以某种方式获取该func的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)

      }


3 个答案:

答案 0 :(得分:3)

您可以从以下位置更改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)
}

编辑: 对于推视图控制器,您应该这样做。抱歉,如果我现在正在使用手机时键入错误的内容。

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)

}

答案 1 :(得分:1)

按照@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
    }
    

答案 2 :(得分:0)

您可以使用节标题内的集合视图委托didSelectItem,并通过使用以下代码访问导航堆栈中的topMost viewcontroller,从而从节可重用视图直接将其推送到配置文件viewcontroller。

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(,动画:true)