web-dev-qa-db-de.com

Wie kann ich indexPath.row in cell.swift erhalten?

Ich habe 2 Dateien.

  • myTableViewController.Swift
  • myTableCell.Swift

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?

16
Shawn Baek

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) }
}
26
Callam

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
}
5
Rakesha Shastri

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
3
Tarvo Mäesepp

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
 }
2
GSK

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.

1
vadian

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?
}

 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
}
1
ossamacpp

Swift 5:

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

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)

}
0
Reimond Hill