Как я могу получить indexPath.row в cell.swift

У меня есть 2 файла.

  • myTableViewController.swift
  • myTableCell.swift

Можно ли получить indexPath.row в функции myTabelCell.swift?

Вот 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



 }

Как вы можете видеть... Я пытаюсь получить indexPath.row в myTableCell, liktBtnTapped.

Не могли бы вы сообщить мне, как я могу получить доступ или получить IndexPath.row?

Ответ 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) }
}

Ответ 2

Свифт 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
}

Ответ 3

Легко.. Вы можете сделать это внутри действия кнопки:

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

Ответ 4

Создайте свойство indexPath в классе ячейки и установите его в cellForRowAtIndexPath, когда ячейка повторно используется.

Но есть оговорка: некоторые методы представления таблиц для переупорядочения ячеек не вызывают cellForRowAtIndexPath. Вы должны рассмотреть этот случай.

Но если вы всегда используете только reloadData(), это безопасно и довольно легко.


Еще один способ - перевести код управления элементами управления в класс контроллера и запустить его через блокировки обратного вызова, фиксирующие индексный путь.

Ответ 5

Вот еще один способ сделать это

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)



}


}

Ответ 6

Мое решение было подклассифицировано UITableViewCell, поэтому можно добавить свойство IndexPath. назначить пользовательский класс для ячейки таблицы в раскадровке. присвойте значение IndexPath при вызове rowAtIndexPath.

class MyTableViewCell: UITableViewCell {

    var indexPath: IndexPath?
}

custom class

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

Свифт 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
 }

Ответ 8

Еще один подход к Swift 4.2 и отсутствие допущения, что Superview всегда будет табличным представлением

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)

}

Ответ 9

Свифт 5:

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