iOS Development
Number Pad Keyboard
Done Button
Swift Programming
User Interface Design

How to show Done button on iOS number pad keyboard?

Interview Questions practice on Codemia

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

Browse interview questions

Introduction

The iOS numberPad keyboard is intentionally minimal: it gives you digits, but no Return or Done key. That often surprises people the first time they build a numeric form. The standard fix is to keep the system keyboard and attach a small accessory toolbar above it with a Done button that dismisses the current responder.

Why returnKeyType does not solve it

On a normal text keyboard, setting returnKeyType = .done changes the label and behavior of the return key. On numberPad and decimalPad, there is no return key to configure, so that property has no visible effect.

This is an important design constraint in UIKit: you cannot inject extra keys into the system number pad. What you can customize is the accessory area above the keyboard through inputAccessoryView.

UIKit solution with UIToolbar

The usual approach is to create a UIToolbar, add a flexible spacer and a Done button, then assign the toolbar to the text field's inputAccessoryView.

swift
1import UIKit
2
3final class PaymentViewController: UIViewController {
4    private let amountField = UITextField()
5
6    override func viewDidLoad() {
7        super.viewDidLoad()
8
9        view.backgroundColor = .systemBackground
10
11        amountField.borderStyle = .roundedRect
12        amountField.placeholder = "Amount"
13        amountField.keyboardType = .numberPad
14        amountField.inputAccessoryView = makeDoneToolbar()
15
16        amountField.translatesAutoresizingMaskIntoConstraints = false
17        view.addSubview(amountField)
18
19        NSLayoutConstraint.activate([
20            amountField.centerXAnchor.constraint(equalTo: view.centerXAnchor),
21            amountField.centerYAnchor.constraint(equalTo: view.centerYAnchor),
22            amountField.widthAnchor.constraint(equalToConstant: 220)
23        ])
24    }
25
26    private func makeDoneToolbar() -> UIToolbar {
27        let toolbar = UIToolbar()
28        toolbar.sizeToFit()
29
30        let spacer = UIBarButtonItem(
31            barButtonSystemItem: .flexibleSpace,
32            target: nil,
33            action: nil
34        )
35
36        let done = UIBarButtonItem(
37            barButtonSystemItem: .done,
38            target: self,
39            action: #selector(dismissKeyboard)
40        )
41
42        toolbar.items = [spacer, done]
43        return toolbar
44    }
45
46    @objc private func dismissKeyboard() {
47        amountField.resignFirstResponder()
48    }
49}

This works well because it preserves the familiar system keyboard and adds only the missing action.

Reusing the pattern across multiple fields

Most forms have more than one numeric input, so it is worth moving the toolbar setup into an extension. That keeps the view controller smaller and makes the behavior consistent across the app.

swift
1import UIKit
2
3extension UITextField {
4    func attachDoneToolbar(target: Any, action: Selector) {
5        let toolbar = UIToolbar()
6        toolbar.sizeToFit()
7
8        let spacer = UIBarButtonItem(
9            barButtonSystemItem: .flexibleSpace,
10            target: nil,
11            action: nil
12        )
13
14        let done = UIBarButtonItem(
15            barButtonSystemItem: .done,
16            target: target,
17            action: action
18        )
19
20        toolbar.items = [spacer, done]
21        inputAccessoryView = toolbar
22    }
23}

Usage stays simple:

swift
amountField.keyboardType = .numberPad
amountField.attachDoneToolbar(target: self, action: #selector(dismissKeyboard))

If you have several fields and want a Next button as well, the same toolbar pattern scales easily. You can add another UIBarButtonItem and move focus to the next responder before finishing with Done.

SwiftUI uses a keyboard toolbar

In SwiftUI, you do not usually set inputAccessoryView directly. The modern equivalent is a toolbar item placed on the keyboard.

swift
1import SwiftUI
2
3struct AmountEntryView: View {
4    @State private var amount = ""
5    @FocusState private var amountFocused: Bool
6
7    var body: some View {
8        Form {
9            TextField("Amount", text: $amount)
10                .keyboardType(.numberPad)
11                .focused($amountFocused)
12        }
13        .toolbar {
14            ToolbarItemGroup(placement: .keyboard) {
15                Spacer()
16                Button("Done") {
17                    amountFocused = false
18                }
19            }
20        }
21    }
22}

The idea is the same as UIKit: keep the stock number pad and add the dismissal control above it.

Common Pitfalls

A common mistake is expecting returnKeyType to magically add a Done key to numberPad. It will not, because that keyboard layout has no return key to relabel.

Another frequent bug is wiring the toolbar correctly but forgetting to dismiss the responder. If the button does not call resignFirstResponder(), it looks right and still does nothing.

Some teams overbuild this by creating a custom keyboard. That usually gives you more code, more testing burden, and less native behavior than a simple accessory toolbar.

Also test decimalPad separately if your form allows decimal input. It has the same no-Done-key limitation, so it typically needs the same solution.

Summary

  • The iOS number pad does not include a built-in Done key.
  • 'returnKeyType does not help because the keyboard layout has no return button.'
  • In UIKit, attach a UIToolbar to inputAccessoryView.
  • Make the Done action call resignFirstResponder() to dismiss editing.
  • In SwiftUI, use a keyboard toolbar item for the same behavior.

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.