UITableView
animation detection
iOS development
beginUpdates endUpdates
Swift programming

How to detect that animation has ended on UITableView beginUpdates/endUpdates?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

beginUpdates() and endUpdates() animate row and section changes, but they do not provide a completion handler of their own. If you need to run code after the animation really finishes, the usual solution is to wrap the update block in a CATransaction and set a completion block there.

Why code after endUpdates() is not enough

endUpdates() schedules the animation work, but it does not mean the visual transition is already complete. If you call another UI operation immediately afterward, you are often racing the table view's own animation and layout pass.

That is why patterns such as "call endUpdates() and then push another change on the next line" can behave inconsistently.

Use CATransaction for a completion callback

Core Animation lets you group the table-view animation into a transaction and run code when that transaction completes.

swift
1import UIKit
2
3CATransaction.begin()
4CATransaction.setCompletionBlock {
5    print("Table view animation finished")
6}
7
8tableView.beginUpdates()
9tableView.reloadRows(at: [IndexPath(row: 0, section: 0)], with: .automatic)
10tableView.endUpdates()
11
12CATransaction.commit()

This is the standard answer when you must keep beginUpdates and endUpdates. The completion block runs after the associated layer animations finish, which is the moment most callers actually care about.

Prefer newer APIs when available

If you are free to change the update style, performBatchUpdates is often cleaner because it includes a completion closure directly.

swift
1tableView.performBatchUpdates({
2    tableView.reloadRows(at: [IndexPath(row: 0, section: 0)], with: .automatic)
3}) { finished in
4    print("Finished: \(finished)")
5}

That API communicates intent more clearly and avoids the need to manage a Core Animation transaction manually.

Keep the data source and UI in sync

A completion callback only helps if the update itself is valid. Before the animation starts, the table view's data source must already reflect the inserted, deleted, or reloaded rows. If the model and the visible operations disagree, the table view can throw an invalid update exception long before any completion logic matters.

That is why post-animation work should be treated as a final step, not as a substitute for getting the batch update right in the first place.

What not to rely on

Using DispatchQueue.main.async is not a reliable animation-completion signal. It only waits for another turn of the run loop, not for the table-view animation to finish. Sometimes it looks like it works; sometimes it fires too early.

Likewise, guessing with a fixed delay is fragile. Animation timing can vary with system state, user settings, and what else is happening in the interface.

What to do after completion

A real completion callback is especially useful for follow-up UI work such as scrolling to a newly inserted row, starting a second animation, or enabling controls that were temporarily disabled during the transition. Those actions should happen after the table view settles, not just after the update call returns.

Common Pitfalls

  • Assuming the line after endUpdates() runs after the animation is visually complete.
  • Using DispatchQueue.main.async as a fake completion callback.
  • Forgetting that the data source must already match the table updates when the animation starts.
  • Nesting batch updates and making completion timing harder to reason about.
  • Ignoring performBatchUpdates when you actually control the API choice.

Summary

  • 'beginUpdates() and endUpdates() do not provide a built-in completion handler.'
  • Wrap the update block in a CATransaction and use setCompletionBlock to detect animation end.
  • If possible, prefer performBatchUpdates because it already exposes completion.
  • Do not use fixed delays or DispatchQueue.main.async as a substitute for real completion.
  • Keep table-view state and data-source changes synchronized before the animation begins.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track 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.

Browse interview questions

All Rights Reserved.