web-dev-qa-db-fra.com

obtenir indexPath de UITableViewCell en cliquant sur le bouton depuis la cellule

 Please Look at this image

J'ai un bouton (croix de couleur rouge) dans la UITableViewCell et en cliquant dessus, je veux obtenir indexPath de la UITableViewCell

En ce moment, j'attribue une balise à chacun des boutons comme celui-ci cell.closeButton.tag = indexPath.section Et en cliquant sur le bouton, j'obtiens la valeur indexPath.section comme ceci:

@IBAction func closeImageButtonPressed(sender: AnyObject) {
  data.removeAtIndex(sender.tag)
  tableView.reloadData()
}

Est-ce la bonne façon de mettre en œuvre ou existe-t-il une autre façon propre de le faire?

7
Anirudha Mahale

Utilisez les délégués:

MyCell.Swift:

import UIKit

//1. delegate method
protocol MyCellDelegate: AnyObject {
    func btnCloseTapped(cell: MyCell)
}

class MyCell: UICollectionViewCell {
    @IBOutlet var btnClose: UIButton!

    //2. create delegate variable
    weak var delegate: MyCellDelegate?

    //3. assign this action to close button
    @IBAction func btnCloseTapped(sender: AnyObject) {
        //4. call delegate method
        //check delegate is not nil with `?`
        delegate?.btnCloseTapped(cell: self)
    }
}

MyViewController.Swift:

//5. Conform to delegate method
class MyViewController: UIViewController, MyCellDelegate, UITableViewDataSource,UITableViewDelegate {

    //6. Implement Delegate Method
    func btnCloseTapped(cell: MyCell) {
        //Get the indexpath of cell where button was tapped
        let indexPath = self.collectionView.indexPathForCell(cell)
        print(indexPath!.row)
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCellWithIdentifier("MyCell") as! MyCell
        //7. delegate view controller instance to the cell
        cell.delegate = self

        return cell
    }
}
30
Bista

Comment obtenir un indexPath de cellule pour un bouton dans Swift 4 avec un sélecteur de bouton

@objc func buttonClicked(_sender:UIButton){

 let buttonPosition = sender.convert(CGPoint.zero, to: self.tableView)
 let indexPath = self.tableView.indexPathForRow(at:buttonPosition)
 let cell = self.tableView.cellForRow(at: indexPath) as! UITableViewCell
 print(cell.itemLabel.text)//print or get item
}
1

Dans votre cellForRow:

#import <objc/runtime.h>

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    setAssociatedObject(object: YOURBUTTON, key: KEYSTRING, value: indexPath)
}

@IBAction func closeImageButtonPressed(sender: AnyObject) {
    let val = getAssociatedObject(object: sender, key: KEYSTROKING)
}

Ici val est votre objet indexPath, votre peut transmettre n'importe quel objet comme vous pouvez affecter un objet de cellule de passe et l'obtenir dans une action de bouton.

0
user1624741

essaye ça:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    var cell = (tableView.dequeueReusableCell(withIdentifier: "MainViewCell", forIndexPath: indexPath) as! MainTableViewCell)
    cell.myButton().addTarget(self, action: Selector("myClickEvent:event:"), forControlEvents: .touchUpInside)
    return cell
}

cette fonction obtient la position du clic de ligne

@IBAction func myClickEvent(_ sender: Any, event: Any) {
    var touches = event.allTouches()!
    var touch = touches.first!
    var currentTouchPosition = touch.location(inView: feedsList)
    var indexPath = feedsList.indexPathForRow(atPoint: currentTouchPosition)!
    print("position:\(indexPath.row)")
}
0
Prashant Sharma

Vous pouvez également obtenir NSIndexPath à partir de CGPoint de cette façon:

@IBAction func closeImageButtonPressed(sender: AnyObject) {
    var buttonPosition = sender.convertPoint(CGPointZero, to: self.tableView)
    var indexPath = self.tableView.indexPathForRow(atPoint: buttonPosition)!
}
0
Bhavin Ramani

Créez une classe personnalisée de UIButton, déclarez une propriété stockée comme celle-ci et utilisez-la pour extraire l'index assigné de callFroRowAtIndexPath.

class VUIButton: UIButton {
    var indexPath: NSIndexPath = NSIndexPath()
}

C'est la solution de preuve complète que votre indexPath ne se trompera jamais dans aucune condition. Essayez une fois.

0
Mahesh Agrawal
//
//  ViewController.Swift
//  Table
//
//  Created by Ngugi Nduung'u on 24/08/2017.
//  Copyright © 2017 Ngugi Ndung'u. All rights reserved.
//

import UIKit

class ViewController: UITableViewController{

    let identifier = "cellId"
    var items = ["item1", "2", "3"]
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        self.title = "Table"
        tableView.register(MyClass.self, forCellReuseIdentifier: "cellId")
    }

    //Return number of cells you need
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
        return items.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath) as! MyClass
        cell.controller = self
        cell.label.text  = items[indexPath.row]
        return cell

    }

    // Delete a cell when delete button on cell is clicked 
    func delete(cell: UITableViewCell){
        print("delete")
        if let deletePath = tableView.indexPath(for: cell){
            items.remove(at: deletePath.row)
            tableView.deleteRows(at: [deletePath], with: .automatic)
        }

    }

}

class MyClass : UITableViewCell{
    var controller : ViewController?
    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
            super.init(style: style, reuseIdentifier: reuseIdentifier)
            setUpViews()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        fatalError("init(coder:) has not been implemented")
    }

    let label : UILabel = {
        let label = UILabel()
        label.text = "My very first cell"
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()

    let btn : UIButton = {
       let bt = UIButton(type: .system)
        bt.translatesAutoresizingMaskIntoConstraints = false
        bt.setTitle("Delete", for: .normal)


        bt.setTitleColor(.red, for: .normal)
        return bt
    }()

    func handleDelete(){
       controller?.delete(cell: self)
    }
    func setUpViews(){
        addSubview(label)
        addSubview(btn)
        btn.addTarget(self, action: #selector(MyClass.handleDelete), for: .touchUpInside)
        btn.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
        label.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 16).isActive = true
        label.widthAnchor.constraint(equalTo: self.widthAnchor , multiplier: 0.8).isActive = true
        label.rightAnchor.constraint(equalTo: btn.leftAnchor).isActive = true

    }
}

Voici un exemple complet qui répondra à votre question. 

0
Sam Ngugi

Dans Swift 4, utilisez simplement ceci:

func buttonTapped (_ expéditeur: UIButton) {

let buttonPostion = sender.convert(sender.bounds.Origin, to: tableView)

if let indexPath = tableView.indexPathForRow(at: buttonPostion) {
    let rowIndex =  indexPath.row
}

}

0
DEEPAK KUMAR