【问题标题】:How can I get indexPath.row in cell.swift如何在 cell.swift 中获取 indexPath.row
【发布时间】:2017-03-19 03:58:33
【问题描述】:

我有 2 个文件。

  • myTableViewController.swift
  • myTableCell.swift

我可以在 myTabelCell.swift 函数中获取 indexPath.row 吗?

这里是 myTableCell.swift

import UIKit
import Parse
import ActiveLabel

class myTableCell : UITableViewCell {

    //Button
    @IBOutlet weak var commentBtn: UIButton!
    @IBOutlet weak var likeBtn: UIButton!
    @IBOutlet weak var moreBtn: UIButton!


    override func awakeFromNib() {
        super.awakeFromNib()


    }

    @IBAction func likeBtnTapped(_ sender: AnyObject) {

        //declare title of button
        let title = sender.title(for: UIControlState())

        //I want get indexPath.row in here!

    }

这里是 myTableViewController.swift

class myTableViewController: UITableViewController {

    //Default func
    override func viewDidLoad() {
        super.viewDidLoad()

        //automatic row height
        tableView.estimatedRowHeight = 450
        tableView.rowHeight = UITableViewAutomaticDimension



    }

 // cell config
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {


        //define cell
        let cell = tableView.dequeueReusableCell(withIdentifier: "myTableCell", for: indexPath) as! myTableCell



 }

如您所见...我试图在 myTableCell 中获取 indexPath.row,liktBtnTapped 函数。

能否告诉我如何访问或获取 IndexPath.row?

【问题讨论】:

    标签: swift uitableview nsindexpath


    【解决方案1】:

    我创建了一个带有递归方法的UIResponder 扩展,您可以在任何UIView(继承自UIResponder)中使用它来查找特定类型的父视图。

    import UIKit
    
    extension UIResponder {
        /**
         * Returns the next responder in the responder chain cast to the given type, or
         * if nil, recurses the chain until the next responder is nil or castable.
         */
        func next<U: UIResponder>(of type: U.Type = U.self) -> U? {
            return self.next.flatMap({ $0 as? U ?? $0.next() })
        }
    }
    

    使用它,我们可以扩展UITableViewCell,为表格视图和单元格的索引路径提供一些方便的只读计算属性。

    extension UITableViewCell {
        var tableView: UITableView? {
            return self.next(of: UITableView.self)
        }
    
        var indexPath: IndexPath? {
            return self.tableView?.indexPath(for: self)
        }
    }
    

    您可以在示例中使用它:

    @IBAction func likeBtnTapped(_ sender: AnyObject) {
        //declare title of button
        let title = sender.title(for: UIControlState())
    
        //I want get indexPath.row in here!
        self.indexPath.flatMap { print($0) }
    }
    

    【讨论】:

    • 看起来很棒的扩展。你介意把代码如何使用吗?
    • 只需创建一个名为UITableViewCell+IndexPath.swift 的新文件并附加上面的代码。然后在您的单元格内,您可以使用self.indexPath 获取索引路径。
    • 这段代码做出了一个假设,根据 iOS 的版本,这个假设可能正确,也可能不正确。您不应该假设表格视图单元格的超级视图是表格视图本身。永远不要对 UITableView 的私有子视图结构做出假设。
    • @rmaddy 没错,但是,您可以假设表格视图单元格至少是表格视图的后代。我已更新我的答案以使用 UIResponder 下一个属性查找表视图。最终,最好的解决方案是在出列时简单地将索引路径传递给单元格,但每个人都喜欢一点魔法。
    • @Callam 不,最好不要将索引路径传递给单元格。这实际上是最糟糕的解决方案。如果可以在表视图中插入、删除或移动行,它会非常失败。
    【解决方案2】:

    斯威夫特 5:

            if 
                let collectionView = superview as? UICollectionView, 
                let index = collectionView.indexPath(for: self) 
            {
                // stuff
            }
    

    【讨论】:

      【解决方案3】:

      Swift 4+

      在你的牢房里试试这个。

      func getIndexPath() -> IndexPath? {
          guard let superView = self.superview as? UITableView else {
              print("superview is not a UITableView - getIndexPath")
              return nil
          }
          indexPath = superView.indexPath(for: self)
          return indexPath
      }
      

      【讨论】:

        【解决方案4】:

        Swift 4.2 的另一种方法,不假设 Superview 将始终是 tableview

        extension UITableViewCell{
        
            var tableView:UITableView?{
                return superview as? UITableView
            }
        
            var indexPath:IndexPath?{
                return tableView?.indexPath(for: self)
            }
        
        }
        

        使用示例

        @IBAction func checkBoxAction(_ sender: UIButton) {
        
                guard let indexPath = indexPath else { return }
        
                sender.isSelected = !sender.isSelected
                myCustomCellDelegate?.checkBoxTableViewCell(didSelectCheckBox: sender.isSelected, for: indexPath)
        
        }
        

        【讨论】:

          【解决方案5】:

          斯威夫特 4.1。在这里,我创建了获取 IndexPath 的函数。只需传递您的 UIView(UIButton,UITextField 等) 和 UITableView 对象即可获取 IndexPath。

          func getIndexPathFor(view: UIView, tableView: UITableView) -> IndexPath? {
          
                      let point = tableView.convert(view.bounds.origin, from: view)
                      let indexPath = tableView.indexPathForRow(at: point)
                      return indexPath
           }
          

          【讨论】:

            【解决方案6】:

            我的解决方案是继承 UITableViewCell,所以可以添加 IndexPath 属性。为情节提要中的表格视图单元分配自定义类。在调用 rowAtIndexPath 时分配 IndexPath 值。

            class MyTableViewCell: UITableViewCell {
            
                var indexPath: IndexPath?
            }
            

            override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            
                var cell = tableView.dequeueReusableCell(withIdentifier: "cellid1", for: indexPath)
                (cell as? MyTableViewCell)?.indexPath = indexPath
                return cell
            }
            

            【讨论】:

              【解决方案7】:

              这是另一种方法

              import UIKit
              import Parse
              import ActiveLabel
              
              class myTableCell : UITableViewCell {
              
              //Button
              @IBOutlet weak var commentBtn: UIButton!
              @IBOutlet weak var likeBtn: UIButton!
              @IBOutlet weak var moreBtn: UIButton!
              
              
              override func awakeFromNib() {
                  super.awakeFromNib()
              
              
              }
              
              
              }
              
              
              class myTableViewController: UITableViewController {
              
              //Default func
              //assuming you have an array for your table data source
              var arrayOfTitles = [String]()
              override func viewDidLoad() {
                  super.viewDidLoad()
              
                  //automatic row height
                  tableView.estimatedRowHeight = 450
                  tableView.rowHeight = UITableViewAutomaticDimension
              
              
              
              }
              
              // cell config
              override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
              
              
              //define cell
              let cell = tableView.dequeueReusableCell(withIdentifier: "myTableCell", for: indexPath) as! myTableCell
              cell.commentBtn.tag = indexPath.row
              cell.commentBtn.addTarget(self, action: #selector(likeBtnTapped(_:), forControlEvents:.TouchUpInside)
              
              
              //cell config end
              
              
              @IBAction func likeBtnTapped(sender: UIButton) {
              let btn = sender
              let indexP = NSIndexPath(forItem: btn.tag, inSection: 0)
              let cell = tableView.dequeueReusableCell(withIdentifier: "myTableCell", for: indexP) as! myTableCell
              
                  //I want get indexPath.row in here!
                  let title = arrayOfTitles[indexP.row]
              
                  //declare title of button
                  cell.commentBtn.setTitle(title, forState: UIControlState.Normal)
              
              
              
              }
              
              
              }
              

              【讨论】:

                【解决方案8】:

                在cell类中创建一个属性indexPath,在cell被复用的时候设置在cellForRowAtIndexPath中。

                但有一点需要注意:某些重新排列单元格的表格视图方法不会调用cellForRowAtIndexPath。你必须考虑这种情况。

                但如果您始终只使用reloadData(),它既安全又非常简单。


                另一种方法是将有关控制事物的代码放回控制器类中,并通过捕获索引路径的回调闭包运行它。

                【讨论】:

                  【解决方案9】:

                  简单..你可以在按钮操作中这样做:

                  let section = 0
                  let row = sender.tag
                  let indexPath = IndexPath(row: row, section: section)
                  let cell: myTableCell = self.feedTableView.cellForRow(at: indexPath) as! myTableCell
                  

                  然后在cellForRowAtIndexPath:

                  // add the row as the tag
                  cell.button.tag = indexPath.row
                  

                  【讨论】:

                  • 能否将您的 cmets 粘贴到我的代码中?我已将您的代码粘贴到 likeBtnTapped 函数中。而是自己。 myTableViewController
                  • 我说的是 YourTableViewCell 不是控制器
                  • 哦,现在我明白了,谢谢
                  • 谢谢,让 indexPath = IndexPath(row: yourIndex, section: section)
                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-04-23
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多