iOS
keyboard management
UI design
scroll view
app development

Tableview scroll content when keyboard shows

Interview Questions practice on Codemia

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

Browse interview questions

Introduction

On iOS, text input inside a UITableView often fails in subtle ways when the keyboard appears. A text field near the bottom may be hidden, scrolling may jump, and insets may never reset after dismissal. These issues come from not coordinating keyboard notifications, safe-area insets, and current first responder position.

A robust implementation must do three things reliably: detect keyboard frame changes, adjust table insets to keep content reachable, and scroll the active input into view. It should also handle modern behaviors like interactive dismissal and different keyboard heights (hardware keyboard, QuickType, split keyboard on iPad). This guide shows a practical Swift approach that works in production forms and settings screens.

Core Sections

Observe keyboard frame notifications

Use keyboardWillChangeFrame instead of only keyboardWillShow/Hide, because frame changes happen during rotation and interactive transitions.

swift
1final class FormViewController: UITableViewController {
2    private var keyboardObserver: NSObjectProtocol?
3
4    override func viewDidAppear(_ animated: Bool) {
5        super.viewDidAppear(animated)
6        keyboardObserver = NotificationCenter.default.addObserver(
7            forName: UIResponder.keyboardWillChangeFrameNotification,
8            object: nil,
9            queue: .main
10        ) { [weak self] note in
11            self?.handleKeyboard(note)
12        }
13    }
14
15    override func viewDidDisappear(_ animated: Bool) {
16        super.viewDidDisappear(animated)
17        if let obs = keyboardObserver { NotificationCenter.default.removeObserver(obs) }
18    }
19}

This single notification keeps logic centralized and less brittle.

Compute bottom inset relative to view coordinates

Keyboard frames in notifications are in screen coordinates. Convert before calculating overlap.

swift
1private func handleKeyboard(_ note: Notification) {
2    guard
3        let userInfo = note.userInfo,
4        let keyboardFrame = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect,
5        let duration = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double,
6        let curveRaw = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? UInt
7    else { return }
8
9    let keyboardInView = view.convert(keyboardFrame, from: nil)
10    let overlap = max(0, view.bounds.maxY - keyboardInView.minY - view.safeAreaInsets.bottom)
11
12    UIView.animate(withDuration: duration,
13                   delay: 0,
14                   options: UIView.AnimationOptions(rawValue: curveRaw << 16),
15                   animations: {
16        self.tableView.contentInset.bottom = overlap
17        self.tableView.scrollIndicatorInsets.bottom = overlap
18        self.scrollActiveFieldIntoView()
19    })
20}

Using overlap logic avoids hard-coded keyboard heights.

Track and scroll the active input cell

When editing begins, capture the active input so you can scroll it into visible bounds.

swift
1private weak var activeView: UIView?
2
3@objc private func editingDidBegin(_ sender: UIView) {
4    activeView = sender
5}
6
7private func scrollActiveFieldIntoView() {
8    guard let active = activeView else { return }
9    let rect = active.convert(active.bounds, to: tableView)
10    tableView.scrollRectToVisible(rect.insetBy(dx: 0, dy: -16), animated: false)
11}

Attach editingDidBegin to text fields/text views in cells. This improves user experience in long forms.

Handle dismissal and gesture behavior

A simple quality upgrade is letting users drag the table to dismiss keyboard.

swift
1override func viewDidLoad() {
2    super.viewDidLoad()
3    tableView.keyboardDismissMode = .interactive
4}

Also ensure you reset insets when keyboard is gone (overlap becomes zero in the frame-change handler).

Prefer content insets over frame changes

Avoid manually resizing the table view frame for keyboard handling. Frame mutations can conflict with Auto Layout and safe areas. Insets are designed for this problem and play nicely with dynamic cell heights.

swift
1// Good: adjust insets
2self.tableView.contentInset.bottom = overlap
3
4// Avoid: changing tableView.frame in keyboard callbacks

This keeps layout predictable across devices and orientation changes.

Common Pitfalls

  • Listening only to keyboardWillShow and missing intermediate frame changes during rotation or interactive dismissal.
  • Calculating overlap in screen coordinates without converting keyboard frame to the controller’s view space.
  • Forgetting to update scrollIndicatorInsets, which leaves scroll bars misaligned with visible content.
  • Resizing view frames directly, causing Auto Layout conflicts and jumpy animations.
  • Not tracking the current first responder, so the user still cannot see the field they are editing.

Summary

Keyboard-safe table view forms require notification-driven inset updates plus focused scrolling to the active input. Use keyboardWillChangeFrame, convert coordinates correctly, compute overlap against safe area, and animate inset changes with the keyboard’s timing curve. Keep logic in one handler and avoid frame hacks. With these patterns, text input remains visible and smooth across device sizes, orientation changes, and modern keyboard behaviors.


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.