【问题标题】:How to grab indexPath item from a collection view cell for a delegate?如何从代表的集合视图单元格中获取 indexPath 项?
【发布时间】:2020-01-26 06:06:43
【问题描述】:

我有一个包含部分标题的 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)


    }

总而言之,我只需要一种方法来获取 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)

      }


【问题讨论】:

  • 你为什么不把它传进去 protocol PeopleToFollowDelegate { func handleProfileTapped(for cell: FeedReusableView, indexPath:IndexPath) }
  • 我不知道如何传递索引路径
  • @AbuUlHassan 或者我真的应该说,我什至不知道在 indexPath 代码中放什么。
  • 分享你使用协议函数的方式和位置handleProfileTapped(: FeedReusableView)
  • @Andrew21111 完成先生

标签: ios swift uicollectionview pushviewcontroller


【解决方案1】:

您可以从

更改 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)

}

【讨论】:

  • 它仍然将我发送到我自己的个人资料。请记住 didSelect 来自 CollectionViewReuseableView,因此我必须在另一个具有视图控制器的文件中创建函数 handleProfilesTapped 以便我可以推送。但是,在创建函数时,我无法获取 peopleToFollow indexPath,因为我没有在 collectionView 的 didSelect 函数中编写代码
  • 如果在 didSelectItemAt indexPath 中设置断点并在控制台中打印用户,如po peopleToFollow[indexPath.item],会得到什么结果
  • 它返回 这是索引中的第一个用户,这就是我想要的。但是,当我选择它时,我会被推送到我自己的个人资料,而不是我正在点击的索引中的用户
  • 所以您在这里找到了正确的用户。现在放一个断点@objc func profilesTapped(user: User),你必须在这里找到正确的用户。之后检查您分配用户的用户配置文件实例。是否获得正确的价值
  • 快乐编码:)
【解决方案2】:

正如@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
    }
    

【讨论】:

    【解决方案3】:

    您可以在部分标题中使用集合视图委托 didSelectItem 并通过使用以下代码访问导航堆栈中的 topMost 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(, animated: true)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多