Ich habe 2 Dateien.
Kann ich die indexPath.row in der Funktion myTabelCell.Swift beziehen?
Hier ist 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!
}
Hier ist 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
}
Wie Sie sehen können, versuche ich indexPath.row in myTableCell, die Funktion liktBtnTapped.
Können Sie mir mitteilen, wie ich auf IndexPath.row zugreifen kann?
Ich habe eine UIResponder
-Erweiterung mit einer rekursiven Methode erstellt, die Sie in jeder UIView
(die von UIResponder
erbt) verwenden können, um eine übergeordnete Ansicht eines bestimmten Typs zu finden.
import UIKit
extension UIResponder {
func next<T: UIResponder>(_ type: T.Type) -> T? {
return next as? T ?? next?.next(type)
}
}
Mit dieser Option können wir UITableViewCell
um einige praktische schreibgeschützte Eigenschaften für die Tabellenansicht und den Indexpfad der Zelle erweitern.
extension UITableViewCell {
var tableView: UITableView? {
return next(UITableView.self)
}
var indexPath: IndexPath? {
return tableView?.indexPath(for: self)
}
}
So können Sie es in Ihrem Beispiel verwenden:
@IBAction func likeBtnTapped(_ sender: AnyObject) {
//declare title of button
let title = sender.title(for: UIControlState())
//I want get indexPath.row in here!
indexPath.flatMap { print($0) }
}
Swift 4+
Versuchen Sie es in Ihrer Zelle.
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
}
Einfach .. Sie können dies innerhalb der Tastenaktion tun:
let section = 0
let row = sender.tag
let indexPath = IndexPath(row: row, section: section)
let cell: myTableCell = self.feedTableView.cellForRow(at: indexPath) as! myTableCell
Und danach in cellForRowAtIndexPath
:
// add the row as the tag
cell.button.tag = indexPath.row
Schnell 4.1. Hier habe ich eine Funktion erstellt, um IndexPath zu erhalten. Übergeben Sie einfach Ihr UIView (UIButton, UITextField usw.) und Ihr UITableView-Objekt, um IndexPath zu erhalten.
func getIndexPathFor(view: UIView, tableView: UITableView) -> IndexPath? {
let point = tableView.convert(view.bounds.Origin, from: view)
let indexPath = tableView.indexPathForRow(at: point)
return indexPath
}
Heres eine andere Weise, es zu tun
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)
}
}
Erstellen Sie eine Eigenschaft indexPath
in der Zellklasse und legen Sie sie bei cellForRowAtIndexPath
fest, wenn die Zelle wiederverwendet wird.
Es gibt jedoch eine Einschränkung: Einige Tabellensichtmethoden zum Umordnen der Zellen rufen nicht cellForRowAtIndexPath
auf. Sie müssen diesen Fall berücksichtigen.
Wenn Sie jedoch immer nur reloadData()
verwenden, ist das sicher und ziemlich einfach.
Eine andere Möglichkeit besteht darin, den Code für controlling things in die controller - Klasse zurückzusetzen und über Callback-Closures auszuführen, die den Indexpfad erfassen.
Meine Lösung hat UITableViewCell subclassing, also kann sie die Eigenschaft IndexPath hinzufügen. Weisen Sie der Story-Zelle eine benutzerdefinierte Klasse für die Tabellensicht zu. Weisen Sie den IndexPath-Wert zu, wenn rowAtIndexPath aufgerufen wurde.
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
}
Swift 5:
if
let collectionView = superview as? UICollectionView,
let index = collectionView.indexPath(for: self)
{
// stuff
}
Ein weiterer Ansatz für Swift 4.2, der nicht davon ausgeht, dass Superview angenommen wird, ist immer eine Tabellenansicht
extension UITableViewCell{
var tableView:UITableView?{
return superview as? UITableView
}
var indexPath:IndexPath?{
return tableView?.indexPath(for: self)
}
}
Verwendungsbeispiel
@IBAction func checkBoxAction(_ sender: UIButton) {
guard let indexPath = indexPath else { return }
sender.isSelected = !sender.isSelected
myCustomCellDelegate?.checkBoxTableViewCell(didSelectCheckBox: sender.isSelected, for: indexPath)
}