I have a UISearchController
with a separate UITableViewController
as its searchResultsController
.
class SearchResultsViewController: UITableViewController {
var fruits: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.tableFooterView = UIView(frame: .zero)
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
}
@objc func addFruit(_ sender: UIButton) {
let point = tableView.convert(sender.bounds.origin, to: sender)
let indexPath = tableView.indexPathForRow(at: point)
print(indexPath?.row)
}
// MARK: - Table view data source
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return fruits.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = fruits[indexPath.row]
cell.selectionStyle = .none
let addButton = UIButton(type: .custom)
addButton.frame = CGRect(x: 0, y: 0, width: 44, height: 44)
addButton.setImage(UIImage(named: "add"), for: .normal)
addButton.contentMode = .scaleAspectFit
addButton.addTarget(self, action: #selector(addFruit(_:)), for: .touchUpInside)
addButton.sizeToFit()
cell.accessoryView = addButton
return cell
}
}
I need to show a custom button in cells that search results are shown. So I added a UIButton
as the cells' accessoryView
. And it looks and works fine.
Now I need to get the cell's indexPath
when the user taps on this button.
I'm trying to get it like shown below.
@objc func addFruit(_ sender: UIButton) {
let point = tableView.convert(sender.bounds.origin, to: sender)
let indexPath = tableView.indexPathForRow(at: point)
}
But it keeps returning nil
for every cell.
Is there any other way to get the indexPath
from a custom button tap? I added a demo project here as well.
Create a custom class named SOButton
and add variable of type IndexPath
to it. Use this class for your add button initialisation.
//Your class will look like -
class SOButton: UIButton {
var indexPath: IndexPath?
}
//Your action will look like -
@objc func addFruit(_ sender: SOButton) {
print(sender?.indexPath.row)
}
//And in your cellForRow add
let addButton = SOButton(type: .custom)
addButton.indexPath = indexPath
Hope this helps you :)