Liumx31
Liumx31

Reputation: 1210

Get the custom UITableViewCell that contains the UIButton pressed

So I have a custom UITableViewCell class:

class customCell{
     let button1 = UIButton()
     let view1 = UIView()
     view1.frame = CGRectMake(30, 60, 10, 10)
     view1.backgroundColor = UIColor.blueColor()
     button1.frame = CGRectMake(10,10,50,50)
     button1.addTarget(tableView(), action: "test:", forControlEvents: .TouchUpInside)
}

And this is what my view controller looks like, with irrelevant code omitted:

class tableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate{
    let table = UITableView()
    let currentCell = customCell()
    var selectedIndexPath: NSIndexPath? = nil

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        selectedIndexPath = indexPath
        let cell = table.cellForRowAtIndexPath(indexPath) as! customCell
        currentCell = cell
        table.beginUpdates()
        tableView.endUpdates()
    }

   func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
       if (selectedIndexPath != nil && indexPath.row == selectedIndexPath!.row && indexPath.section == selectedIndexPath!.section){
           return 155
        }
       return 90
    }

   func test(sender:UIButton){
       currentCell.view1.hidden = true // does not work    
   }
}

As marked in the code, when I use currentCell to hold the cell selected and try to manipulate its subviews, i.e. hide a subview, it does not work. It seems like currentCell does not refer to the selected cell in the tableView at all.

Upvotes: 3

Views: 226

Answers (2)

Nicolas Miari
Nicolas Miari

Reputation: 16246

You can find out the index path with this code:

@IBAction func buttonAction(sender: UIButton) {

    let point = sender.convertPoint(CGPointZero, toView: tableView)

    let indexPath = tableView.indexPathForRowAtPoint(point)

    // (use your index path)
}

Next, you could manually call self.tableView(_:cellForRowAtIndexPath:) passing the obtained index path, but that will likely configure a new (reused) table view cell instance to display the data associated with that index path (row, section).

If you want to get a hold of the exact same table view cell instance that is on screen and whose button was pressed, you will have to do something different and possibly ugly; perhaps traverse the view hierarchy starting from the button and towards its superviews?


UPDATE: The data source method: tableView(_:cellForRowAtIndexPath:) will definitely configure a different (possibly reused) instance of UITableViewCell, but the UITableView method: cellForRowAtIndexPath() will give you the same instance that is on screen.

It is not mentioned in the docs for UITAbleView, but I made a sample project to test it:

TableViewController.swift

/* 
   Table cells are of custom subclass TableViewCell, with one outlet declared like this:

       @IBOutlet weak var button:UIButton!

   The button is connected with this action in the custom UITableViewController subclass that holds the table view:
*/
 @IBAction func buttonAction(sender: UIButton)
 {
        let point = sender.convertPoint(CGPointZero, toView: tableView)

        let indexPath = tableView.indexPathForRowAtPoint(point)

        let cell = tableView.cellForRowAtIndexPath(indexPath!) as! TableViewCell

        let cellButton = cell.button

        if cellButton == sender {
            // Same button instance, means also same 
            // instance of table view cell:

            print ("same instance!")
        }
    }

(nil checks omitted for brevity. In production code, don't force-unwrap optionals!)

Upvotes: 2

SeanChense
SeanChense

Reputation: 846

I don't know Swift much but Obj-c. In fact I think you can put the test: method into the CustomCell class, that is

class customCell{
     let button1 = UIButton()
     let view1 = UIView()
     view1.frame = CGRectMake(30, 60, 10, 10)
     view1.backgroundColor = UIColor.blueColor()
     button1.frame = CGRectMake(10,10,50,50)
     button1.addTarget(tableView(), action: "test:", forControlEvents:                 .TouchUpInside)

    func test(sender:UIButton){
       self.view1.hidden = true    
    }
}

Upvotes: 2

Related Questions