【问题标题】:How to get indexPath when image inside cell tapped点击单元格内的图像时如何获取indexPath
【发布时间】:2018-02-12 05:13:07
【问题描述】:

我想实现一个功能,如果 profileImage 在 tableviewCell 中点击,则转到 detailView。我添加了 tapGesture 但我仍然无法弄清楚如何让 indexPath 传递数据。 我试过这样,但应用程序会崩溃。

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

        if segue.identifier == "detailSegue" {
            let next: DetailViewController = segue.destination as! DetailViewController
          // pattern1
 let indexPath = tableView.indexPath(for: sender as! CustomTableViewCell)
         // pattern2
        let indexPath = tableView.indexPathForSelectedRow! as NSIndexPath

            next.data = datas[indexPath.row]
        }
    }

我该如何解决这个问题?提前谢谢!

【问题讨论】:

标签: swift uitableview nsindexpath


【解决方案1】:

如果您将UITapGestureRecognizer 添加到UIImageView,则不要 忘记将isUserInteractionEnabled 属性设置为true

创建一个变量来存储选中的indexPath.row

var selectedCell:Int!

cellForRow 方法中向图像视图添加手势。

let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.tapBtnAction(_:)))
cell.imageView.tag = indexPath.row
cell.imageView.addGestureRecognizer(tapGesture)

在目标方法中执行segue

func tapBtnAction(_ sender: UITapGestureRecognizer) {
    print("\(sender.view.tag) Tapped")
    self.selectedCell = sender.view.tag
    self.performSegueWithIdentifier("detailSegue", sender: self)
}

prepareforsegue方法中从数组中获取数据。

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

   if segue.identifier == "detailSegue" {
      let next: DetailViewController = segue.destination as! DetailViewController
       next.data = datas[self.selectedCell]
   }
}

【讨论】:

  • 这对我有用,它应该是选择的答案,因为它涵盖了所有方面
【解决方案2】:

1:在cellForRowAtIndexpath方法中设置ImageView的tag,tag等于indexPath.row

imgView.tag = indexPath.row

2:在 imageView 上附加一个目标到 tapGuestureRecognizer

3:在该方法中获取imageView的标签

let imgView = sender as! UIImageView
let tag = imgView.tag

4:相应地获取数据,并推送

let next = self.storyBoard.instatiateViewController(WithIdentifer:"detailVC") 
next.data = datas[tag]
self.navigationController.pushViewController(next)

【讨论】:

    【解决方案3】:

    解决方案一:使用 touchBegun 方法,确保 imageView UserInteraction 开启

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        let touch = touches.first
          if let cell = touch?.view?.superview?.superview as? YourCellClass {
            let indexPath = yourTablView.indexPath(for: cell)
        //Do whatever you want
        }
    }
    

    解决方案2:你可以使用按钮。

    @IBAction func onBtnClick(_ sender : UIButton) {
        if let cell = sender.superview?.superview as? UITableViewCell {
            let indexPath = tbl_songsInfo.indexPath(for: cell)
        //Do whatever you want
        }
    }
    

    解决方案 3:与上述相同,但使用 sender.tag

    @IBAction func onBtnClick(_ sender : UIButton) {
        let data = yourDataArray[sender.tag] 
        //Do whatever you want
    }
    

    【讨论】:

    • 这是一个非常脆弱的解决方案,应该避免。此代码依赖于未记录的UITableView 子视图结构和对发送者如何添加到单元格的假设的组合。有更简单、更安全的解决方案。
    【解决方案4】:

    我制作了一个示例项目来演示解决方案。它工作得很好。看动图!

    您可以使用链接下载示例项目代码 https://drive.google.com/file/d/1zF8Uq2H6eQYyrHU6KqnZu7b5cU_HtZY0/view?usp=sharing

    实际上,您必须为您的图像添加一个手势识别器,并为该手势附加一个动作。请参阅 cellforRowAt 的实现。

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
     let cell = tableView.dequeueReusableCell(withIdentifier:"TableViewCellUser") as! TableViewCellUser
     //handle image and its gesture
    
     cell.imgUser.image = userImagesArray[indexPath.row]
     //enable the interaction so that touch could be captured.
     cell.imgUser.isUserInteractionEnabled = true
     let gesture = UITapGestureRecognizer(target: self, action:  #selector(userImageTapped(gesture:)))
     gesture.numberOfTouchesRequired = 1
     gesture.delegate = self as? UIGestureRecognizerDelegate
     cell.imgUser.tag = indexPath.row
     cell.imgUser.addGestureRecognizer(gesture)
     //handle label
     cell.lblUserName.text = userNames[indexPath.row]
     return cell
    

    }

    //用户点击时的动作

    guard let indexPathRow = gesture.view?.tag else {
      return
    }
    print(indexPathRow)
    guard indexPathRow >= 0 else {
      print("Array index must be greater than zero. Going to  return")
      return
    }
    selectedUserImage = userImagesArray[indexPathRow]
    selectedUserName = userNames[indexPathRow]
    self.performSegue(withIdentifier: "UsersToDetail", sender: self)
    

    您可以从上述链接下载完整的工作代码。如果出现任何问题,请在 cmets 中告诉我

    此链接也将有所帮助 [UITapGestureRecognizer tag]: unrecognized selector sent to instance

    【讨论】:

      【解决方案5】:

      有多种方法可以实现这一点,但最简单的方法是在 UIImageView 上方添加 UIButton。 并相对于 UITableViewCell 的 IndexPath 设置 UIButton 的标签,并添加 UIButton 的点击事件。

      cell.btnImage.tag = indexPath.row
      

      当用户尝试点击 UIImage 时,图片上方的 UIButton 将被点击并触发按钮的点击事件,在这里您可以获取被点击的 UIButton 的索引,该索引与该特定单元格中的 UIImageView 相同.

      @IBAction func BtnClick(_ sender : UIButton) {
      
           print(sender.tag)//here you will get the IndexPath for that particular UIImageView in Cell.
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-30
        • 2017-01-27
        • 1970-01-01
        • 1970-01-01
        • 2020-09-27
        相关资源
        最近更新 更多