Getting row of UITableView cell on button press
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
When a button lives inside a UITableViewCell, the button action does not automatically tell you which row triggered it. The clean solution is to map that tap back to an IndexPath, either by asking the table view for the touched cell location or, even better, by wiring the cell to report actions through a callback.
Quick Approach: Convert the Button Position to an IndexPath
If you already have a button target action and want the row immediately, convert a point from the button into the table view's coordinate space.
This works well for simple screens. The key step is indexPathForRow(at:), not reading a stored row number from the button itself.
Better Design: Let the Cell Report Its Own Action
For maintainable code, avoid making the view controller search the hierarchy every time. A cleaner pattern is to let the cell expose a closure or delegate, then ask the table view for the cell's index path when the callback fires.
This scales better because the cell owns the button interaction and the controller owns the data lookup.
Why Button Tags Are Fragile
You will often see code like:
That works in small demos, but it becomes fragile when rows move, sections are added, or data is reloaded asynchronously. Tags are just integers with no table-view semantics, so they are easy to desynchronize from the actual cell state.
If the table can reorder, insert, or delete rows, deriving the IndexPath at tap time is much safer.
Keep the Real Model ID Nearby
Even when you know the row, what you often really want is the underlying item identifier. In practice, the best architecture is usually:
- map the tap to an
IndexPath - use the
IndexPathto look up the model - act on the model's stable identifier
That prevents UI position from becoming the business identifier accidentally.
Common Pitfalls
- Storing
indexPath.rowinbutton.tagand assuming it will stay correct after reloads or inserts. - Searching the superview chain manually to find the cell, which is brittle against layout changes.
- Ignoring sections and using only
rowwhen the table has multiple sections. - Capturing the wrong cell in a reused table-view cell without updating callbacks during configuration.
- Treating the visible row as the real data identity instead of mapping back to the model object.
Summary
- The direct fix is to convert the button position and ask the table view for the matching
IndexPath. - A cleaner long-term pattern is a cell callback combined with
tableView.indexPath(for:). - Avoid relying on
button.tagfor anything beyond tiny demos. - Use the row to find the model, not as the final business identifier.
- Table-view cell reuse makes explicit configuration and callback wiring important.
Related reading
- Getting the current Fragment instance in the viewpager
- Getting the difference between two Dates months/days/hours/minutes/seconds in Swift
- Getting the difference between two Dates months/days/hours/minutes/seconds in Swift
- getting the screen density programmatically in android?
- Getting the Value of a UITextField as keystrokes are entered?
- Getting version and build information with Swift
- Getting version and build information with Swift
- Git ignore file for Xcode projects
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.