How to know when accessory view is tapped

Where do I put code to run when the user taps the accessory view of a table view cell but not tap the content view of the cell?

@brower Thanks very much for your question. If I understand your question correctly, you’re referring to calling code to execute after the user presses the chevron (i.e. the arrow) on the UITableViewCell correct? If this is the case, my guess would be to include the code inside the prepareForSegue method. I would like to point out here that it would not be recommended to make a distinction between a user pressing the accessoryView vs pressing the cell itself (i.e. the contentView). The space is very narrow, and have multiple triggers inside a UITableViewCell would be confusing to the user. In fairness, the accessoryView is just that, an “accessory”. Meaning, it assists the user to know that there is more content available if the user selects the row.

Try to ensure that your UI/UX is simple, and easy to follow so as to not confuse the user. If what you’re trying to do is coming across as being too complex, my guess would be that you should take a step back, and try to simply your workflow. :slight_smile:

I hope this helps!

All the best!

Other than what @syedfa says, you can do what you want by implementing your own UITableViewCell. Subclass a UITableViewCell and create a button on the place of the accessoryview, or add a tapgesture to the accessoryview. Then you can handle the actionMethod in this cell subclass, which can call a method in the viewcontroller if you supply the cell with a delegate.

I hope you succeed. The Human Interface Guidelines are good, but sometimes you want to do something special.

When you say supply the cell with a delegate, do you mean there is a protocol for table view cell delegate? Like UITableViewCellDelegate that I can extend by the view controller subclass?

Hi,
What I meant was, when you either create or re-use the tableviewcell, you set the delegate variable (which you need to define yourself) to the (table)viewcontroller.
For this you create a protocol class with one function, e.g.
protocol AccessoryProtocol class {
func accessoryTapped(YourCellClass)
}
The delegate var should be of this AccessoryProtocol type.

In the AccessoryProtocol extension of your table)viewcontroller, you implement this function.

Now, the trick is to discover which cell is clicked in.

For this I set either the model object involved, or the index of the cell data in the array in the cell.

Good luck!

I found this tutorial before I saw your explanation. It looks like this tutorial is showing the same thing as your explanation above.

I actually found a different approach to solving the problem. I used the addTarget method of the button in my table view cell to point the button tap action to a selector in the view controller, and for the target argument in the addTarget method I typed the name of the view controller class with “()” after it. I don’t know what that means, but it works. I think I got the idea from the suggestions that Xcode gives to correct errors. I tried just adding the name of the view controller class without the “()” and I got an error with the suggestion to add the “()” after the name of the view controller class.

I guess it depends on where you call the addTarget method. If you call it in the viewcontroller you can also use ‘self’ as a target.
What happens if you use ViewController(), is that you instantiate a NEW viewcontroller, which will not have access to data in the old viewcontroller.

Depending on what you want to accomplish, this may not be what you want.
Try to access a data structure from the viewcontroller after you tapped a button.

Cheers

I follow your logic, but for some reason the code works. I was able to access data on the view controller, so apparently putting the “()” after the name of the view controller acquires the view controller as a singleton. Just my guess.

I have no idea what all these other answers are talking about as they don’t seem to relate at all to your question. You specifically asked where code should run if you tap on the ACCESSORY VIEW of a UITableViewCell. That’s exactly what the UITableViewDelegate method tableView(_:accessoryButtonTappedForRowWith:) is for.

1 Like

@brower My apologies, but @gargoyle is correct. I feel really stupid looking back on this question.

tableView(_:accessoryButtonTappedForRowWith:) seems to never been called if we are using a custom accessory view.

e.g:
If my cell was declared like that
let view = UIImageView(image: R.image.add())
view.isUserInteractionEnabled = true
view.frame = CGRect(x: 0, y: 0, width: 20, height: 20)
cell.accessoryView = view

tableView(_:accessoryButtonTappedForRowWith:) will never be called.

Where, if it was declared like this:

cell.accessoryType = .detailButton

tableView(_:accessoryButtonTappedForRowWith:) will be called.

So how can we handle click on custom accessoryView ?

@jintuscoding Do you still have issues with this?