iOS Development
UITableView
Swift Programming
Mobile App Development
User Interface Design

UITableView Add content offset at top

Interview Questions practice on Codemia

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

Browse interview questions

Introduction

When developers say they want to “add content offset at the top” of a UITableView, they usually mean one of two different things. They either want visible space above the first row, or they want the table to start scrolled down. Those are related, but they are not the same API operation.

Know the Difference Between Inset and Offset

contentOffset is the current scroll position. contentInset adds padding around the scrollable content. If you want extra space above the first cell, adding a top inset is usually the right move. If you only change the offset, the table may snap back or start in a strange position because there is no actual padding to scroll into.

For top spacing, set both the inset and the initial offset:

swift
1override func viewDidLayoutSubviews() {
2    super.viewDidLayoutSubviews()
3
4    let extraTopSpace: CGFloat = 32
5
6    tableView.contentInset.top = extraTopSpace
7    tableView.scrollIndicatorInsets.top = extraTopSpace
8    tableView.setContentOffset(
9        CGPoint(x: 0, y: -tableView.adjustedContentInset.top),
10        animated: false
11    )
12}

This creates real room above the content and positions the table so that room is visible immediately.

Why adjustedContentInset Matters

On modern iOS, safe areas and automatic inset adjustment can add their own top padding. If you ignore that and hardcode y = -32, the result may be off by the navigation bar or status bar inset.

Using adjustedContentInset.top is safer because it includes the system-adjusted value that the table is actually using at layout time. That makes the initial offset more reliable across devices and container layouts.

If You Want a Visual Spacer, Consider a Header View

Sometimes you do not need scroll mechanics at all. You just want space or decoration above the first row. In that case, a table header view is often clearer than manipulating offsets:

swift
let spacer = UIView(frame: CGRect(x: 0, y: 0, width: tableView.bounds.width, height: 32))
spacer.backgroundColor = .clear
tableView.tableHeaderView = spacer

This creates a stable visual gap without affecting scroll math. If the goal is a hero banner, logo, or introductory text, tableHeaderView is usually the more maintainable solution.

Apply the Change at the Right Time

Timing matters. If you set the offset too early, Auto Layout and safe-area adjustments may override your values later. viewDidLayoutSubviews or viewDidAppear is often safer than viewDidLoad for initial scroll positioning.

For example:

swift
1override func viewDidAppear(_ animated: Bool) {
2    super.viewDidAppear(animated)
3    tableView.setContentOffset(
4        CGPoint(x: 0, y: -tableView.adjustedContentInset.top),
5        animated: false
6    )
7}

Use this approach when layout is still changing after viewDidLoad, such as inside navigation controllers or when dynamic headers are involved.

Account for Automatic Inset Behavior

If you need total control, you may also need to manage automatic inset adjustment:

swift
tableView.contentInsetAdjustmentBehavior = .never

That disables system adjustment, but it also means you are responsible for safe-area handling yourself. Use it only when the default behavior is actively getting in the way.

Pull to Refresh and Top Offset

If the table uses UIRefreshControl, remember that extra top inset changes how the refresh indicator feels. This is not wrong, but it means the pull distance and resting position may differ from the default behavior. Test the interaction on a device, not just in a static screenshot.

Also remember to keep the scroll indicator aligned by updating scrollIndicatorInsets whenever you change contentInset. Otherwise the scrollbar can overlap content or appear visually off.

Common Pitfalls

The most common mistake is setting contentOffset without adding matching contentInset. That changes the current position, but it does not create top space, so the result often snaps back or looks wrong.

Another pitfall is doing the work in viewDidLoad, then wondering why the table ends up somewhere else once safe areas are applied. Layout timing matters for scroll views.

It is also easy to forget adjustedContentInset. Hardcoded offsets may work on one device and fail on another with a different navigation or status-bar layout.

Finally, if your actual goal is a visual spacer or header, forcing the effect through scroll offset alone makes the code harder to reason about than necessary.

Summary

  • Use contentInset.top to create real space above the first table row.
  • Use contentOffset only to choose the visible scroll position within that padded content.
  • Prefer adjustedContentInset.top when setting the initial top position.
  • Consider tableHeaderView if the goal is a visual spacer rather than scroll behavior.
  • Apply the change after layout so safe-area and navigation insets are already known.

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.