Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIButton not responding used in a custom UITableViewCell

I know this issue is already been asked few times in SO. Despite trying those out, I am still unable to solve my problem.

I am using a UITableView inside a UIViewController. I have a custom UITableViewCell which has couple of buttons in it. However, I am not able to make the Button respond to Click event.

The development environment is iOS 9 and Swift 2

Snippets used :

BranchNearMeTableViewCell.swift contains

@IBOutlet weak var btnDetails: UIButton!

view controller class

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("branchNearTableCell") as! BranchNearMeTableViewCell

 cell.btnDetails.tag = indexPath.row
        cell.btnDetails.addTarget(self, action: "showDetails:", forControlEvents: .TouchUpInside)

}

func showDetails(sender: UIButton){

        print("Button Pressed:")
    }

Additional Info:

TableView and TableCellView has User interaction disabled in Interface builder since don't want the entire cell to be clickable.

UIButton inside TableViewCell has User Interaction enabled.

Being an iOS noob, I may be making a silly mistake which I might have overlooked.

Similar questions that I checked include:

SO1

SO2

SO3

I Deeply appreciate any help regarding this question.

like image 874
user2695433 Avatar asked Feb 12 '16 08:02

user2695433


4 Answers

I faced a similar issue. I was programmatically adding an UIButton to the UITableViewCell via addSubview. The button would not respond to touch events. Using Debug View Hierarchy, I finally discovered that any subviews added to the UITableViewCell was behind contentView, which was blocking user input from reaching the UIButton. The issue was resolved by adding the UIButton to contentView instead of the UITableViewCell.

like image 86
Peter Liaw Avatar answered Nov 09 '22 09:11

Peter Liaw


I would have userInteractionEnabled set to true on the table view cell as well. I would prevent taps using the UITableView allowsSelection to false

Also remember to remove the target and action in tableView:cellForRowAtIndexPath: since the cells are recycled, the button might already have the target and action, it might add a second.

like image 12
Kyle Redfearn Avatar answered Nov 09 '22 09:11

Kyle Redfearn


I found a simple solution:

Inherits UITableViewCell, and override init()

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
    //init subviews, eg. self.switch = UISwitch()
    super.init(style: style, reuseIdentifier: reuseIdentifier)
                
    // add this line magic code 
    contentView.isUserInteractionEnabled = true
                
    //add subviews, e.g. self.addSubView(self.switch)
}
like image 9
luffy Avatar answered Nov 09 '22 09:11

luffy


For programmatically created views, the only thing to remember is to declare buttons using lazy var in UITableViewCell. And also add subviews to contentView instead of the cell itself For example:

class CounterCell: UITableViewCell {

    lazy var incrementButton: UIButton = {
        let button = UIButton()
        button.setTitle("+", for: .normal)
        button.addTarget(self, action: #selector(incrementAction), for: .touchUpInside)
        return button
    }()

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        contentView.addSubview(incrementButton)
        // Your constrains here
    }

    @objc func incrementAction() {
    }

}

When using programmatically views, there's no need to add .userInteractionEnabled flags.

Then to take the action out of the cell, just add a delegate and assign it from the UITableViewDataSource.

like image 3
Camilo Ortegón Avatar answered Nov 09 '22 09:11

Camilo Ortegón