web-dev-qa-db-fra.com

Comment puis-je obtenir indexPath.row dans cell.swift

J'ai 2 fichiers.

  • myTableViewController.Swift
  • myTableCell.Swift

Puis-je obtenir le fichier indexPath.row dans la fonction myTabelCell.Swift?

Voici 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!

    }

Voici 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



 }

Comme vous pouvez le voir ... J'essaie d'obtenir indexPath.row dans myTableCell, fonction liktBtnTapped 

Pourriez-vous me dire comment puis-je accéder ou obtenir IndexPath.row?

16
Shawn Baek

J'ai créé une extension UIResponder avec une méthode récursive que vous pouvez utiliser dans toute UIView (qui hérite de UIResponder) pour trouver une vue parent d'un type spécifique.

import UIKit

extension UIResponder {

    func next<T: UIResponder>(_ type: T.Type) -> T? {
        return next as? T ?? next?.next(type)
    }
}

En utilisant cela, nous pouvons étendre UITableViewCell avec quelques propriétés de calcul pratiques en lecture seule pour la vue de table et le chemin d’index de la cellule.

extension UITableViewCell {

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

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

Voici comment vous pourriez l'utiliser dans votre exemple:

@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+

Essayez ceci dans votre cellule.

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

Facile .. Vous pouvez faire comme ceci dans l'action du bouton:

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

Et ensuite dans cellForRowAtIndexPath:

// add the row as the tag
cell.button.tag = indexPath.row
3
Tarvo Mäesepp

Swift 4.1. Ici, j'ai créé une fonction pour obtenir IndexPath. Il suffit de transmettre vos objets UIView (UIButton, UITextField, etc.) et UITableView pour obtenir 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
 }
2
GSK

Heres une autre façon de le faire 

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)



}


}

Créez une propriété indexPath dans la classe de cellule et définissez-la dans cellForRowAtIndexPath lorsque la cellule est réutilisée.

Mais il y a un avertissement: certaines méthodes d'affichage sous forme de tableau pour réorganiser les cellules n'appellent pas cellForRowAtIndexPath. Vous devez considérer ce cas.

Mais si vous utilisez toujours uniquement reloadData(), c'est simple et sans danger.


Une autre méthode consiste à replacer le code concernant controlling choses dans la classe controller et à l'exécuter via des fermetures de rappel capturant le chemin d'index.

1
vadian

Ma solution était de sous-classer UITableViewCell, donc je peux ajouter la propriété IndexPath attribuer une classe personnalisée pour la cellule de vue tableau dans le storyboard. attribue la valeur IndexPath lorsque rowAtIndexPath a appelé.

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

Une autre approche pour Swift 4.2 et ne pas supposer que Superview sera toujours une vue de table

extension UITableViewCell{

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

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

}

Exemple d'utilisation

@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