UIKit
UITableView
iOS Development
Swift Programming
TextField Handling

Making a UITableView scroll when text field is selected

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

When a text field inside a table view becomes first responder, the keyboard can cover the active row. The fix is to adjust table insets for keyboard height and scroll the active cell into view. A robust implementation must handle dynamic keyboard sizes, animation timing, and responder changes.

Track the Active Text Field

You need to know which text field is currently editing so the table can scroll to the correct row.

swift
1import UIKit
2
3final class FormViewController: UITableViewController, UITextFieldDelegate {
4    private weak var activeField: UITextField?
5
6    override func viewDidLoad() {
7        super.viewDidLoad()
8        NotificationCenter.default.addObserver(
9            self,
10            selector: #selector(keyboardWillChangeFrame(_:)),
11            name: UIResponder.keyboardWillChangeFrameNotification,
12            object: nil
13        )
14        NotificationCenter.default.addObserver(
15            self,
16            selector: #selector(keyboardWillHide(_:)),
17            name: UIResponder.keyboardWillHideNotification,
18            object: nil
19        )
20    }
21
22    deinit {
23        NotificationCenter.default.removeObserver(self)
24    }
25
26    func textFieldDidBeginEditing(_ textField: UITextField) {
27        activeField = textField
28        scrollActiveFieldIntoView(animated: true)
29    }
30
31    func textFieldDidEndEditing(_ textField: UITextField) {
32        if activeField === textField {
33            activeField = nil
34        }
35    }
36}

Tracking the active field prevents incorrect scrolling when multiple text fields exist.

Adjust Insets with Keyboard Notifications

Update contentInset and scrollIndicatorInsets to reserve visible space above the keyboard.

swift
1import UIKit
2
3extension FormViewController {
4    @objc func keyboardWillChangeFrame(_ note: Notification) {
5        guard
6            let info = note.userInfo,
7            let frame = info[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect,
8            let duration = info[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double,
9            let curveValue = info[UIResponder.keyboardAnimationCurveUserInfoKey] as? UInt
10        else { return }
11
12        let keyboardFrameInView = view.convert(frame, from: nil)
13        let intersection = view.bounds.intersection(keyboardFrameInView)
14        let bottomInset = max(0, intersection.height - view.safeAreaInsets.bottom)
15
16        let options = UIView.AnimationOptions(rawValue: curveValue << 16)
17        UIView.animate(withDuration: duration, delay: 0, options: options) {
18            self.tableView.contentInset.bottom = bottomInset
19            self.tableView.scrollIndicatorInsets.bottom = bottomInset
20            self.scrollActiveFieldIntoView(animated: false)
21        }
22    }
23
24    @objc func keyboardWillHide(_ note: Notification) {
25        tableView.contentInset.bottom = 0
26        tableView.scrollIndicatorInsets.bottom = 0
27    }
28}

Using keyboard animation values keeps table movement synchronized with keyboard transitions.

Scroll the Active Field Precisely

Convert the active field bounds into table coordinates and call scrollRectToVisible.

swift
1import UIKit
2
3extension FormViewController {
4    func scrollActiveFieldIntoView(animated: Bool) {
5        guard let field = activeField else { return }
6
7        let rect = field.convert(field.bounds, to: tableView)
8        let padded = rect.insetBy(dx: 0, dy: -16)
9        tableView.scrollRectToVisible(padded, animated: animated)
10    }
11}

This works even when text fields are nested inside custom cell subviews.

Alternative for Newer iOS Versions

On newer iOS versions, keyboardLayoutGuide can simplify layout-based keyboard avoidance. However, table forms still often need explicit scroll behavior to keep the active control centered.

If you choose layout guides, keep active-field scrolling logic because inset adjustment alone may not place the field comfortably above the keyboard.

Integrate with Validation and Return Navigation

Forms usually need next-field navigation and validation messages in addition to keyboard avoidance. Implement textFieldShouldReturn to move focus to the next visible field and call the same scroll helper after focus changes. If validation labels appear below a field, trigger another scroll pass after updating constraints so the message is not hidden by the keyboard. Keeping keyboard handling and validation updates coordinated prevents jumpy animations and reduces user frustration on long forms.

Common Pitfalls

A common mistake is hard-coding keyboard height. Different devices, hardware keyboards, and split keyboards produce variable heights.

Another issue is forgetting to remove keyboard observers, causing duplicate inset updates or crashes on deallocated controllers.

Developers also scroll by index path but fail when cells contain multiple fields. Field-based rect conversion is more precise.

Finally, avoid immediate scrolling before keyboard animation begins. Use keyboard notifications so movement is synchronized and visually stable.

Keep this behavior covered by UI tests that focus every field in sequence.

Summary

  • Track the active text field with delegate callbacks.
  • Update table insets using keyboard frame notifications.
  • Scroll the exact active field rect into view.
  • Sync animations with keyboard duration and curve values.
  • Remove observers and avoid hard-coded keyboard sizes.

Course illustration
Course illustration

All Rights Reserved.