Как я могу получить 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
}