J'ai 2 fichiers.
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?
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) }
}
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
}
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
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
}
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.
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?
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "cellid1", for: indexPath)
(cell as? MyTableViewCell)?.indexPath = indexPath
return cell
}
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)
}