I have a UITableView, and in each of the UITableViewCells, I have a button, which should perform an action when selected. If the user decides the select the actual cell, I handle another action within the didSelectRowAt function. I am not sure if I am missing something, but my button does not work when selected, but performs the didSelectRowAt function.
The layout and constraints work just fine. It is just not recognizing the tap, and then pushes to the didSelectRowAt
class MyProfile: UIViewController, UITableViewDelegate, UITableViewDataSource {
let tableView : UITableView = {
let tableView = UITableView()
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.separatorStyle = .none
tableView.backgroundColor = UIColor.white
return tableView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(tableView)
tableView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 10).isActive = true
tableView.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
tableView.rightAnchor.constraint(equalTo: self.view.rightAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 10).isActive = true
view.backgroundColor = UIColor.white
tableView.delegate = self
tableView.dataSource = self
tableView.register(ProfileCell.self, forCellReuseIdentifier: "profileCell")
// data and backend stuff to reload tableview has been removed, so there is not too much code
// Do any additional setup after loading the view.
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
self.myServices.text = "My Services"
return myJobs.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "profileCell", for: indexPath) as! ProfileCell
cell.selectionStyle = .none
cell.deleteButton.addTarget(self, action: #selector(deletePostPressed), for: .touchUpInside)
cell.editButton.addTarget(self, action: #selector(editPostPressed), for: .touchUpInside)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.navigationController?.pushViewController(ViewPostController(), animated: true)
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 175
}
@objc func deletePostPressed() {
print("delete")
}
@objc func editPostPressed() {
print("edit")
self.present(Home(), animated: true, completion: nil)
}
}
class ProfileCell: UITableViewCell {
let editButton : UIButton = {
let button = UIButton(type: .system)
button.setTitle("Edit", for: .normal)
button.setTitleColor(UIColor.mainBlue, for: .normal)
button.backgroundColor = UIColor(red: 240/255, green: 240/255, blue: 240/255, alpha: 1)
button.isUserInteractionEnabled = true
button.translatesAutoresizingMaskIntoConstraints = false
button.layer.borderWidth = 1
button.layer.borderColor = UIColor.mainBlue.cgColor
return button
}()
let deleteButton : UIButton = {
let button = UIButton(type: .system)
button.setTitle("Delete", for: .normal)
button.setTitleColor(UIColor.mainBlue, for: .normal)
button.backgroundColor = UIColor(red: 240/255, green: 240/255, blue: 240/255, alpha: 1)
button.isUserInteractionEnabled = true
button.translatesAutoresizingMaskIntoConstraints = false
button.layer.borderWidth = 1
button.layer.borderColor = UIColor.mainBlue.cgColor
return button
}()
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
self.selectionStyle = .none
}
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
isUserInteractionEnabled = true
addSubview(editButton)
editButton.layer.cornerRadius = 15
editButton.layer.masksToBounds = true
editButton.topAnchor.constraint(equalTo: saleNumber.bottomAnchor, constant: 7).isActive = true
editButton.rightAnchor.constraint(equalTo: informationView.rightAnchor, constant: -15).isActive = true
editButton.heightAnchor.constraint(equalToConstant: 30).isActive = true
editButton.widthAnchor.constraint(equalToConstant: 85).isActive = true
addSubview(deleteButton)
deleteButton.layer.cornerRadius = 15
deleteButton.layer.masksToBounds = true
deleteButton.topAnchor.constraint(equalTo: saleNumber.bottomAnchor, constant: 7).isActive = true
deleteButton.rightAnchor.constraint(equalTo: editButton.leftAnchor, constant: -15).isActive = true
deleteButton.heightAnchor.constraint(equalToConstant: 30).isActive = true
deleteButton.widthAnchor.constraint(equalToConstant: 85).isActive = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
I am not sure what else could be the problem. I have declared delegates, corrected everything, and made sure everything else that needed to be initialized was, and still it doesn't work.
It's a matter of hierarchy, you need to add the buttons to the contentView
. If you just add a subview
to the view
, it goes behind the contentView
of the UITableViewCell
.
Visually, where the selected one is the contentView
of the cell, you can see that the actual button is behind it:
So contentView.addSubview(editButton)
and contentView.addSubview(deleteButton)
does the job.