How to access the content of a custom cell in swift using button tag?

我是研究僧i 提交于 2019-12-27 11:12:32

问题


I have an app that has a custom button in a custom cell. If you select the cell it segues to the a detail view, which is perfect. If I select a button in a cell, the code below prints the cell index into the console.

I need to access the contents of the selected cell (Using the button) and add them to an array or dictionary. I am new to this so struggling to find out how to access the contents of the cell. I tried using didselectrowatindexpath, but I don't know how to force the index to be that of the tag...

So basically, if there are 3 cells with 'Dog', 'Cat', 'Bird' as the cell.repeatLabel.text in each cell and I select the buttons in the rows 1 and 3 (Index 0 and 2), it should add 'Dog' and 'Bird' to the array/dictionary.

    // MARK: - Table View

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return postsCollection.count
}

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

    let cell: CustomCell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomCell

    // Configure the cell...
    var currentRepeat = postsCollection[indexPath.row]
    cell.repeatLabel?.text = currentRepeat.product
    cell.repeatCount?.text = "Repeat: " + String(currentRepeat.currentrepeat) + " of " + String(currentRepeat.totalrepeat)

    cell.accessoryType = UITableViewCellAccessoryType.DetailDisclosureButton

    cell.checkButton.tag = indexPath.row;

    cell.checkButton.addTarget(self, action: Selector("selectItem:"), forControlEvents: UIControlEvents.TouchUpInside)


    return cell

}

func selectItem(sender:UIButton){

    println("Selected item in row \(sender.tag)")

 }

回答1:


OPTION 1. Handling it with delegation

The right way of handling events fired from your cell's subviews is to use delegation.

So you can follow the steps:

1. Above your class definition write a protocol with a single instance method inside your custom cell:

protocol CustomCellDelegate {
    func cellButtonTapped(cell: CustomCell)
} 

2. Inside your class definition declare a delegate variable and call the protocol method on the delegate:

var delegate: CustomCellDelegate?

@IBAction func buttonTapped(sender: AnyObject) {
    delegate?.cellButtonTapped(self)
}

3. Conform to the CustomCellDelegate in the class where your table view is:

 class ViewController: CustomCellDelegate

4. Set your cell's delegate

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as CustomCell
    cell.delegate = self

    return cell
}

5. Implement the required method in your view controller class.

EDIT: First define an empty array and then modify it like this:

private var selectedItems = [String]()

func cellButtonTapped(cell: CustomCell) {
    let indexPath = self.tableView.indexPathForRowAtPoint(cell.center)!
    let selectedItem = items[indexPath.row]

    if let selectedItemIndex = find(selectedItems, selectedItem) {
        selectedItems.removeAtIndex(selectedItemIndex)
    } else {
        selectedItems.append(selectedItem)
    }
}

where items is an array defined in my view controller:

private let items = ["Dog", "Cat", "Elephant", "Fox", "Ant", "Dolphin", "Donkey", "Horse", "Frog", "Cow", "Goose", "Turtle", "Sheep"] 

OPTION 2. Handling it using closures

I've decided to come back and show you another way of handling these type of situations. Using a closure in this case will result in less code and you'll achieve your goal.

1. Declare a closure variable inside your cell class:

var tapped: ((CustomCell) -> Void)?

2. Invoke the closure inside your button handler.

@IBAction func buttonTapped(sender: AnyObject) {
    tapped?(self)
}

3. In tableView(_:cellForRowAtIndexPath:) in the containing view controller class :

let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! CustomCell       
cell.tapped = { [unowned self] (selectedCell) -> Void in
    let path = tableView.indexPathForRowAtPoint(selectedCell.center)!
    let selectedItem = self.items[path.row]

    println("the selected item is \(selectedItem)")
}



回答2:


Since you have 1 section in the table view you can get the cell object as below.

let indexPath = NSIndexPath(forRow: tag, inSection: 0)
let cell = tableView.cellForRowAtIndexPath(indexPath) as! CustomCell!

where tag you will get from button tag.




回答3:


Swift 3 I just get solution for access cell in @IBAction function using superview of button tag.

let cell = sender.superview?.superview as! ProductCell
var intQty = Int(cell.txtQty.text!);
intQty = intQty! + 1
let  strQty = String(describing: intQty!);
cell.txtQty.text = strQty



回答4:


@IBAction func buttonTap(sender: UIButton) {
        let button = sender as UIButton
        let indexPath = self.tableView.indexPathForRowAtPoint(sender.center)!
}



回答5:


I updated option 1 of the answer from Vasil Garov for Swift 3

1. Create a protocol for your CustomCell:

protocol CustomCellDelegate {
    func cellButtonTapped(cell: CustomCell)
} 

2. For your TableViewCell declare a delegate variable and call the protocol method on it:

var delegate: CustomCellDelegate?

@IBAction func buttonTapped(sender: AnyObject) {
    delegate?.cellButtonTapped(self)
}

3. Conform to the CustomCellDelegate in the class where your tableView is:

 class ViewController: CustomCellDelegate

4. Set your cell's delegate

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)  as CustomCell
    cell.delegate = self

    return cell
}

5. Implement the required method in your ViewController.




回答6:


Based on Cao's answer, here is a solution to handle buttons in a collection view cell.

    @IBAction func actionButton(sender: UIButton) {
        let point = collectionView.convertPoint(sender.center, fromView: sender.superview)
        let indexPath = collectionView.indexPathForItemAtPoint(point)
}

Be aware that the convertPoint() function call will translate the button point coordinates in the collection view space. Without, indexPath will always refer to the same cell number 0




回答7:


XCODE 8: Important Note

Do not forget to set the tags to a different value than 0.

If you attempt to cast an object with tag = 0 it might work but in some weird cases it doesn't.

The fix is to set the tags to different values. Hope it helps someone.



来源:https://stackoverflow.com/questions/29913066/how-to-access-the-content-of-a-custom-cell-in-swift-using-button-tag

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!