Swiftpack.co - Package - danielsaidi/KeyboardKit

Version Platform Swift 5.1 License Twitter: @danielsaidi

About KeyboardKit

KeyboardKit is a Swift library that helps you create keyboard extensions for iOS. It supports many keyboard actions and keyboard types and lets you create keyboards with text inputs, emojis, actions, images etc.

With KeyboardKit, you inherit KeyboardInputViewController instead of UIInputViewController. This provides you with a keyboardActionHandler that can handle taps, long presses etc. and a keyboardStackView to which you can add components like toolbars, button rows and collection views. KeyboardKit also provides you with tools for haptic feedback, displaying alerts on top of the keyboard etc.


Swift Package Manager

The easiest way to add Sheeeeeeeeet to your project in Xcode 11 is to use Swift Package Manager:



target 'HostApp' do
  pod 'KeyboardKit'

target 'KeyboardExt' do
  pod 'KeyboardKit'


github "danielsaidi/KeyboardKit"

Manual installation

To manually add KeyboardKit to your app, clone this repository, add KeyboardKit.xcodeproj to your project and KeyboardKit.framework as an embedded app binary and target dependency.

Get Started

With KeyboardKit, your input view controllers should inherit from KeyboardInputViewController instead of UIInputViewController. It has a keyboardStackView to which you can add components like toolbars, button rows and even collection views The keuyboard extension will automatically be resized to fit the content of this stack view.

Keyboard Actions

KeyboardKit comes with a set of actions that can be applied to your keyboard buttons, like characters, backspace, newline, space, keyboard switchers etc.

Checkout this guide for more information about the available actions and how to use them.

Keyboard Types

KeyboardKit comes with the following built-in keyboard types:

  • alphabetic(uppercase/lowercase)
  • numeric
  • symbolic
  • email
  • emojis
  • custom(name)

These types are just keyboard representations, without any logic. You can bind them to a keyboard action to add buttons that switches between various keyboard types, but you have to implement the keyboards types yourself.


KeyboardKit comes with a set of component protocols that can be combined into complete keyboard, e.g. vertical and horizontal components, buttons, button rows etc.

Checkout this guide for more information about the available components and how to use them.


KeyboardKit comes with a set of views that implement one or several of the component protocols above, e.g. vertical and horizontal components, buttons, button rows etc.

Checkout this guide for more information about the available views and how to use them.


KeyboardKit supports autocomplete, which means that you can add a toolbar that displays autocomplete suggestions for the currently typed text and replaces text in your text document proxy when you tap a suggestion.

Checkout this guide for more information about how to implement autocomplete in your keyboard.


Since keyboard extensions can't display UIAlertControllers, you can use KeyboardAlert to alert messages on top of the keyboard. You can use the built-in ToastAlert or create a custom one.

Haptic Feedback

KeyboardKit has a set of HapticFeedback variants, that can be used to give the user haptic feedback as she/he uses the keyboard. The HapticFeedback enum defines a set of haptic feedback types that wraps native iOS feedback types like selection changed, error, success etc.


KeyboardKit comes with a bunch of extensions that simplifies working with keyboard extensions. Many are internal and only used within the library, but some are public and can be used to handle common logic, like saving and exporting images. Check out the example app for more information.

Demo Application

This repository contains a demo app that demonstrates different kinds of keyboards, including a grid-based emoji keyboard. To try it out, open and run the KeyboardKit.xcodeproj project.

Contact me

Feel free to reach out if you have questions or if you want to contribute in any way:


KeyboardKit is available under the MIT license. See LICENSE file for more info.


Stars: 178
Help us keep the lights on

Used By

Total: 1


2.3.0 - Jul 18, 2019

This version adds autocomplete support, which includes an autocomplete suggestion provider protocol, a new toolbar and new extensions.

The new AutocompleteSuggestionProvider protocol describes how to provide your keyboard with autocomplete suggestions. You can implement it in any way you like, e.g. to use a built-in suggestion database or by connecting to an external data source, using network requests. Note that the network option will be a lot slower and also require you to request full access from your users.

The new AutocompleteToolbar is a toolbar that can display any results you receive from your suggestion provider (or any list of strings for that matter). Just trigger the provider anytíme the text changes and route the result to the toolbar. The toolbar can be populated with any kind of views. Have a look at the demo app for an example.

The new UITextDocumentProxy+CurrentWord extension helps you get the word that is (most probably) being typed. You could use this when requesting autocomplete suggestions, if you only want to autocomplete the current word.

Besides these additions, there are a bunch of new extensions, like UITextDocumentProxy deleteBackwards(times:), which lets you delete a certain number of characters. Have a look at the Extensions namespace for a complete list.

There is also a new KeyboardShiftState enum that you can use to keep track of which state your keyboard has, if any. This enum is extracted from demo app code that was provided by @arampak earlier this year.

IMPORTANT iOS has a bug that causes textWillChange and textDidChange to not be called when the user types, only when the cursor moves. This causes autocomplete problems, since the current word is not changing as the user types. Due to this, the input view controller must use an ugly hack to force the text document proxy to update. Have a look at the demo app to see how this is done.

2.2.0 - Jul 17, 2019

This version adds more keyboard actions that don't exist in iOS, but that may serve a functional or semantical purpose in your apps:

  • command
  • custom(name:)
  • escape
  • function
  • option
  • tab

The new custom action is a fallback that you can use if the existing action set is insufficient for your specific app.

I have added a RepeatingGestureRecognizer and an extension that you can use to apply it as well. It has a custom initial delay as well as a custom repeat interval, that will let you tap and hold a button to repeat its action. In the next update, I will apply this to the backspace and arrow buttons.

Thanks to @arampak, the demo app now handles shift state and long press better, to make the overall experience much nicer and close to the native keyboard. The keyboard buttons also registers tap events over the entire button area, not just the button view.

2.2.1 - Jul 17, 2019

This version solves some major bugs in the repeating gesture recognizer and makes some public parts of the library open.

The standard action handler now handles repeating actions for backspace. You can customize this in the same way as you customize tap and long press handling.

You can test the new repeating logic in the demo app.

2.1.0 - May 30, 2019

This version makes a bunch of previously internal extensions public, since they are now covered by unit tests. It also adds a lot more unit tests to cover most parts of the library.

The default tap animation has been configured to allow user interaction, which reduces the frustrating tap lag that was present in 2.0.0. Sorry about that!

I have added a KeyboardToolbar class, which you can use to create toolbars. It's super simple so far, and only creates a stack view to which you can any views you like.

2.0.1 - May 19, 2019

This version adds a public shadow extension to the main library and shuffles classes and extensions around. It also restructures the example project to make it less cluttered.

I also noticed that the build number bump randomly bumps the build number incorrectly, which causes build errors. I have therefore abandoned this approach and fixed the build number to 1 in all targets.