Swift
ScrollView
iOS
KeyboardHandling
AppDevelopment

ScrollView and keyboard in Swift

Interview Questions practice on Codemia

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

Browse interview questions

Introduction

Forms inside a UIScrollView often break usability when the keyboard appears and hides active inputs. A reliable solution must handle inset updates, focused-field scrolling, animation timing, and observer lifecycle. Good keyboard handling is less about one callback and more about consistent behavior across rotation, device sizes, and input types.

Listen to Keyboard Frame Changes

keyboardWillChangeFrameNotification is the most practical event because it covers show, hide, and intermediate transitions.

swift
1import UIKit
2
3final class FormViewController: UIViewController {
4    @IBOutlet private weak var scrollView: UIScrollView!
5
6    override func viewDidLoad() {
7        super.viewDidLoad()
8        NotificationCenter.default.addObserver(
9            self,
10            selector: #selector(handleKeyboardFrameChange(_:)),
11            name: UIResponder.keyboardWillChangeFrameNotification,
12            object: nil
13        )
14    }
15
16    deinit {
17        NotificationCenter.default.removeObserver(self)
18    }
19
20    @objc private func handleKeyboardFrameChange(_ note: Notification) {
21        guard
22            let info = note.userInfo,
23            let endFrame = info[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect
24        else { return }
25
26        let keyboard = view.convert(endFrame, from: nil)
27        let overlap = max(0, view.bounds.maxY - keyboard.minY)
28        updateInsets(bottom: overlap, userInfo: info)
29    }
30
31    private func updateInsets(bottom: CGFloat, userInfo: [AnyHashable: Any]) {
32        let duration = (userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0.25
33        let curveRaw = (userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber)?.uintValue ?? 7
34        let options = UIView.AnimationOptions(rawValue: curveRaw << 16)
35
36        UIView.animate(withDuration: duration, delay: 0, options: options) {
37            self.scrollView.contentInset.bottom = bottom
38            self.scrollView.scrollIndicatorInsets.bottom = bottom
39            self.view.layoutIfNeeded()
40        }
41    }
42}

This keeps keyboard and scroll behavior visually synchronized.

Scroll Active Input into View

Insets alone may not reveal the current field. Scroll to the focused control when editing begins.

swift
1extension FormViewController: UITextFieldDelegate {
2    func textFieldDidBeginEditing(_ textField: UITextField) {
3        let fieldRect = textField.convert(textField.bounds, to: scrollView)
4        scrollView.scrollRectToVisible(fieldRect.insetBy(dx: 0, dy: -20), animated: true)
5    }
6}
7
8extension FormViewController: UITextViewDelegate {
9    func textViewDidBeginEditing(_ textView: UITextView) {
10        let textRect = textView.convert(textView.bounds, to: scrollView)
11        scrollView.scrollRectToVisible(textRect.insetBy(dx: 0, dy: -20), animated: true)
12    }
13}

Use the same strategy for UITextView and custom input controls.

Auto Layout and Safe Area Considerations

When the scroll view is constrained to safe areas, make sure inset updates apply to content and indicator insets consistently. If you use additional bottom accessory views, include their height in overlap calculations.

For iPhone models with varying bottom safe area, validate behavior in portrait and landscape. Keyboard height and visible overlap differ significantly across configurations.

Alternative Pattern with Keyboard Layout Guide

On newer iOS versions, keyboard layout guide can simplify manual calculations. It provides a layout anchor that follows keyboard movement.

swift
if #available(iOS 15.0, *) {
    scrollView.bottomAnchor.constraint(equalTo: view.keyboardLayoutGuide.topAnchor).isActive = true
}

This can reduce notification handling complexity, but test compatibility if you still support older OS versions.

Next and Done Accessory Controls

For long forms, adding an input accessory toolbar with Next and Done actions improves completion speed and reduces manual scrolling.

swift
1func makeAccessoryToolbar(next: Selector, done: Selector) -> UIToolbar {
2    let toolbar = UIToolbar()
3    toolbar.sizeToFit()
4    toolbar.items = [
5        UIBarButtonItem(title: "Next", style: .plain, target: self, action: next),
6        UIBarButtonItem.flexibleSpace(),
7        UIBarButtonItem(title: "Done", style: .done, target: self, action: done)
8    ]
9    return toolbar
10}

Accessory controls complement keyboard inset handling and provide a consistent form-navigation experience.

Testing Checklist

Useful test cases:

  • first input near top and last input near bottom,
  • multiline text view growth while keyboard is visible,
  • rotation while editing,
  • hardware keyboard attached,
  • external language keyboard with different heights.

Automated UI tests can verify focus visibility by asserting element hittability after typing actions.

Common Pitfalls

  • Updating insets only on keyboard show and missing frame-change transitions.
  • Forgetting to remove observers and receiving duplicate callbacks.
  • Scrolling wrong container when nested scroll views exist.
  • Ignoring animation timing from keyboard notifications and causing jumpy UI.
  • Handling only text fields while text views remain obscured.

Summary

  • Use keyboard frame change notifications for robust inset handling.
  • Keep focused controls visible by scrolling active inputs into view.
  • Synchronize animations using keyboard duration and curve metadata.
  • Account for safe area and device variation in overlap calculations.
  • Validate behavior with rotation, multiline input, and hardware keyboard scenarios.

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.