How can I get indexPath.row in cell.swift

69,003

Solution 1

I have created a UIResponder extension with a recursive method that you can use in any UIView (which inherits from UIResponder) to find a parent view of a specific type.

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

Using this, we can extend UITableViewCell with some convenient read-only computed properties for the table view and index path of the cell.

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

    var indexPath: IndexPath? {
        return self.tableView?.indexPath(for: self)
    }
}

Here is how you could use it in your example:

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

Solution 2

Swift 4+

Try this inside your cell.

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
}

Solution 3

Easy.. You can do like this inside button action:

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

And afterwards in cellForRowAtIndexPath:

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

Solution 4

Another Approach for Swift 4.2 and not assuming Superview will be always a tableview

extension UITableViewCell{

    var tableView:UITableView?{
        return superview as? UITableView
    }

    var indexPath:IndexPath?{
        return tableView?.indexPath(for: self)
    }

}

Usage example

@IBAction func checkBoxAction(_ sender: UIButton) {

        guard let indexPath = indexPath else { return }

        sender.isSelected = !sender.isSelected
        myCustomCellDelegate?.checkBoxTableViewCell(didSelectCheckBox: sender.isSelected, for: indexPath)

}

Solution 5

Swift 4.1. Here I created function to get IndexPath. Just pass your UIView(UIButton,UITextField etc) and UITableView object to get 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
 }
Share:
69,003
Shawn Baek
Author by

Shawn Baek

Hi there. I'm an iOS Developer living in Seoul, South Korea 🇰🇷 I worked as an UX Engineer over the 6 years and then switching to iOS Engineer. So, UI implementation is one of my strong sides. I also love web development using Javascript, ReactJS, CSS, and HTML. Please visit my blog, I write about iOS Development. https://shawnbaek.com (Sorry, English is my second language 😅)

Updated on February 16, 2022

Comments

  • Shawn Baek
    Shawn Baek over 2 years

    I have 2 files.

    • myTableViewController.swift
    • myTableCell.swift

    Can I get the indexPath.row in myTabelCell.swift function?

    Here is 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!
    
        }
    

    Here is 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
    
    
    
     }
    

    As you can see... I'm trying to get indexPath.row in myTableCell, liktBtnTapped function.

    Could you let me know how can I access or get IndexPath.row?