Get notified when UITableView has finished asking for data?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
UITableView does not have one official callback that means "I am completely done asking for data forever." That is because the table asks for rows lazily as cells become visible, as the user scrolls, and as layout changes.
So the real answer depends on what you actually need to know. Sometimes you want to know when reloadData() has finished laying out visible cells, sometimes when the last currently visible row was displayed, and sometimes when an asynchronous data fetch has finished before the table reload even starts.
Why There Is No Single "Finished" Callback
A table view asks its data source for information in phases:
- number of sections and rows
- cells for visible index paths
- more cells later as the user scrolls
- updated cells again after reloads or batch updates
That means this mental model is important: a table view is not like a one-shot parser that consumes all data once. It is a reusable, on-demand view.
If you are waiting for "finished asking for data," first decide whether you mean:
- finished reloading visible content
- finished displaying the currently visible rows
- finished loading the underlying model from the network or database
Those are different events.
After reloadData(), Use the Next Layout Pass
If your goal is "run code after the table has reloaded and laid out its visible rows," a common pattern is to force layout and then dispatch work to the next main-thread turn:
Usage:
This does not mean the table will never ask for more data again. It only means the current reload cycle for visible content has completed.
Use willDisplay to Detect Visible Cell Completion
If you want to know when the last currently visible row is about to appear, tableView(_:willDisplay:forRowAt:) is often the right delegate hook:
This is useful for pagination triggers or for hiding a loading spinner after the first real content becomes visible.
Distinguish UI Completion from Data Loading Completion
A very common mistake is using table view callbacks to represent data loading. If the actual requirement is "my network request finished and the model is ready," handle that in the async fetch code before reloading the table.
The fetch callback tells you when the data is ready. The table view only tells you about rendering and display.
For Animated Updates, Use Batch Completion
If you are inserting or deleting rows with animation, performBatchUpdates gives you an actual completion callback:
This is more precise than trying to infer completion indirectly from other delegate methods when the update is animated.
Common Pitfalls
- Expecting
cellForRowAtto be called for every row immediately afterreloadData(). - Using table view rendering callbacks as if they were network-loading callbacks.
- Assuming there is one global "done" event even though table views load lazily.
- Forgetting that scrolling can trigger more data requests later.
- Using
willDisplayto detect model completion when it only reflects UI visibility.
Summary
- '
UITableViewhas no single callback meaning it is completely done asking for data.' - After
reloadData(), use layout plus the next main-thread cycle if you need post-reload UI work. - Use
willDisplaywhen you care about visible-row display events. - Use async fetch completions when the real event is data readiness, not table rendering.
- Use
performBatchUpdatescompletion for animated insert or delete operations.

