# Adding a "Done" Button to iOS Numpad in Flutter

> The iOS number keyboard has no Done key, so Flutter users can't dismiss it. Here's a reusable fix with keyboard_actions that adds a Done button above the numpad.

URL: https://dinkomarinac.dev/blog/adding-a-done-button-to-ios-numpad-in-flutter/
Author: Dinko Marinac
Published: 2024-08-19
Tags: tutorial, ios, flutter

## Introduction

This week I had to add an "done" action to a numbers only text field. Seems easy.

```dart
textInputAction: TextInputAction.done
```

Done.

Couple of hours later I got a message: "Doesn't work on iOS".

## Problem

I went on Google to search for a solutions. Stack Overflow suggested to change my keyboard type and add an a `TextInputFormatter` :

```dart
textInputAction: TextInputAction.done,
keyboardType: TextInputType.numberWithOptions(signed: true, decimal: true)
inputFormatters: <TextInputFormatter>[
  FilteringTextInputFormatter.digitsOnly,
],
```

This solution works, but now, the user gets a regular keyboard and can enter anything, which is not the behaviour I am looking for.

I should be able to have only numbers and decimal separators (`.` , `,`) on the keyboard and a done button to finish typing.

After some research, I found the problem → iOS doesn't support this behaviour. Even native developers have their workarounds.

Thankfully, Flutter has a plugin that can help: [KeyboardActions](https://pub.dev/packages/keyboard_actions).

You can use this to add any actions above the keyboard. A great example are Slack and Notion which add buttons for styling about the keyboard in their mobile apps.

## Solution

Here's how it works.

First you need to define all the actions you want to add to this keyboard.

```dart
final FocusNode _focusNode = FocusNode();

KeyboardActionsConfig get _keyboardActionsConfig {
    return KeyboardActionsConfig(
      keyboardActionsPlatform: KeyboardActionsPlatform.ALL,
      keyboardBarColor: const Color(0xFFCAD1D9), //Apple keyboard color
      actions: [
        KeyboardActionsItem(
          focusNode: _focusNode,
          toolbarButtons: [
            (node) {
              return GestureDetector(
                onTap: () => node.unfocus(),
                child: Container(
                  padding: const EdgeInsets.all(12.0),
                  child: Text(
                    S.of(context).done,
                    style: const TextStyle(
                      color: Color(0xFF0978ED), //Done button color
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                ),
              );
            }
          ],
        ),
      ],
    );
  }
```

All "Done" button does is unfocusing of the `TextField` we are currently using, which is where the `onTap` method implementation comes from. I'm using Apple's default coloring here, but you could you anything you want.

After that you need to wrap your `TextField` with the `KeyboardActions` Widget.

```dart
KeyboardActions(
  config: _keyboardActionsConfig,
  disableScroll: true,
  child: TextFormField(
    focusNode: _focusNode, // <-- don't forget to add the focus node
    controller: widget.controller,
    onChanged: (value) {
	    final input = double.tryParse(value) ?? 0
	    //TODO: do something with the input
    }
    labelText: widget.labelText,
    keyboardType:
        const TextInputType.numberWithOptions(decimal: true),
    textInputAction: TextInputAction.done,
  ),
);
```

Make sure not to forget adding the focus node to the field, otherwise this will not work.

The end result looks like this:

![Custom Done button on iOS numpad in Flutter](https://dinkomarinac.dev/images/posts/adding-a-done-button-to-ios-numpad-in-flutter/adding-a-done-button-to-ios-numpad-in-flutter-0.png)

That's it. You made your product manager happy.

If you have found this useful, make sure to like and follow for more content like this. To know when the new articles are coming out, follow me on [**Twitter**](https://twitter.com/dinkomarinac) and [**LinkedIn**](https://www.linkedin.com/in/dinko-marinac/).

Until next time, happy coding!
