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 HapticFeedback type, that can be used to give the user haptic feedback as she/he uses the keyboard. HapticFeedback defines a set of feedback types that wraps native feedback types like selection changed, error, success etc.

You can enable or disable haptic feedback by providing the keyboardActionHandler with a haptic feedback configuration. The default configuration is to disable haptic feedback.

NOTE that you have to enable open access for the keyboard for haptic feedback to work.

Audio Feedback

KeyboardKit has an AudioFeedback type, that can be used to give the user audio feedback as she/he uses the keyboard. AudioFeedback defines a set of feedback types that wraps native system sounds.

You can enable or disable audio feedback by providing the keyboardActionHandler with a audio feedback configuration. The default configuration is to play standard audio feedback.

NOTE that you have to enable open access for the keyboard for haptic feedback to work.


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:

  • Alphabetical (lower + upper-case)
  • Numerical
  • Symbols
  • Emojis
  • Images

To keep the keyboard layout nice, the image switcher key is only displayed on notch devices, since they don't have to display a next keyboard button.

You have to enable "full access" in keyboard settings for haptic feedback and the image keyboard to work.

To run the demo app, 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: 202

Used By

Total: 0


- 2019-12-13 22:09:39

This version adds more autocomplete functionality:

  • AutocompleteToolbar has a new convenience initializer that makes it even easier to setup autocomplete.
  • AutocompleteToolbarLabel is the default autocomplete item view and can be tapped to send text to the text document proxy.
  • AutocompleteToolbarLabel behaves like the native iOS autocomplete view and displays centered text until the text must scroll.
  • Autocomplete no longer requires the bugfix timer to work. Instead, just let the action handler request autocomplete suggestions.

The StandardKeyboardActionHandler has new functionality:

  • animationButtonTap() - can be overridden to change the default animation of tapped buttons.


  • The AutocompleteBugFixTimer and all timer-related logic has been deprecated.
  • The AutoCompleteSuggestionProvider's provideAutocompleteSuggestions(for:completion:) is deprecated and replaced with autocompleteSuggestions(for:completion:).
  • The StandardKeyboardActionHandler's handleXXX(on:) are now deprecated and replaced with handle(:on:view:).

- 2019-10-16 09:24:51

2.5.0 adds new features (like audio feedback), tweaks some behaviors and deprecates some logic:

New stuff:

  • There is a new KeyboardActionGesture that will be used to streamline the action handling api:s.
  • There is a new AudioFeedback enum that describes various types of audio feedback.
  • There is a new AudioFeedbackConfiguration that lets you gather all configurations in one place.
  • There is a new HapticFeedback.standardFeedback(for:) function that replaces the old specific properties.
  • There is a new HapticFeedbackConfiguration that lets you gather all configurations in one place.
  • There is a new StandardKeyboardActionHandler init that uses this new configuration.
  • There is a new StandardKeyboardActionHandler.triggerAudioFeedback(for:) that can be used to trigger audio feedback.
  • There is a new StandardKeyboardActionHandler.triggerHapticFeedback(for:on:) that replaces the old gesture-specific ones.
  • There is a new StandardKeyboardActionHandler.gestureAction(for:) function that is used by the implementation. The old ones are still around.
  • There is a new KeyboardType.images case that is used by the demo.

Changed behavior:

  • There is a new standardButtonShadow Shadow property that can be used to mimic the native button shadow.

Deprecated stuff:

  • The old StandardKeyboardActionHandler.init(...) is deprecated, use the new one.
  • The old StandardKeyboardActionHandler.giveHapticFeedbackForLongPress(...) is deprecated, use the new one.
  • The old StandardKeyboardActionHandler.giveHapticFeedbackForRepeat(...) is deprecated, use the new one.
  • The old StandardKeyboardActionHandler.giveHapticFeedbackForTap(...) is deprecated, use the new one.
  • The old HapticFeedback.standardTapFeedback and standardLongPressFeedback have been replaced by the new function.

The old handle functions are still declared in the KeyboardActionHandler protocol, but will be removed in the next major version.

- 2019-10-15 04:18:43

This version adds Xcode 11 and iOS 13 support, including support for dark mode and high contrast color variants.

- 2019-07-18 11:01:37

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.

- 2019-07-17 23:53:17

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.

- 2019-07-17 23:52:49

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.

- 2019-05-30 14:41:11

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.

- 2019-05-19 15:49:37

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.

- 2019-05-18 18:11:09

This version is a major change that attempt to streamline KeyboardKit and remove or refactor parts that make it hard to maintain. It contains several breaking changes, but I hope that you as a result gets a library that is easier to use and more flexible.

Most notably, the view controller inheritance model has been completely removed. Instead, there is only one KeyboardInputViewController. It has a stack view to which you can add any views you like, like the built-in KeyboardButtonRow and KeyboardCollectionView, which means that your custom keyboards is now based on components that you can combine.

Since KeyboardInputViewController therefore can display multiple keyboards at once, it doesn't make any sense to have a single keyboard property. You can still use structs to organize your actions (in fact, I recommend it - have a look at the demo app), but you don't have to.

All action handling has been moved from the view controller to KeyboardActionHandler as well. KeyboardInputViewController use a StandardActionHandler by default, but you can replace this by setting keyboardActionHandler to any KeyboardActionHandler. This is required if you want to use certain actions types, like .image.

New KeyboardActions are added and nextKeyboard has been renamed to switchKeyboard. Action equality logic has also been removed, so instead of isNone, you should use == .none from now on. All help properties like image and imageName are removed as well, since they belong in the app. These are the new action types

  • capsLock
  • dismissKeyboard
  • moveCursorBackward
  • moveCursorForward
  • shift
  • shiftDown
  • switchToKeyboard(type)

KeyboardInputViewController will now resize the extension to the size of the stack view, or any other size constraints you may set. The old setHeight(to:) function has therefore been removed.

- 2019-05-18 18:08:31

This version upgrades KeyboardKit to Swift 5. It has many breaking changes:

  • KeyboardInputViewController has been renamed to KeyboardViewController
  • CollectionKeyboardInputViewController has been renamed to CollectionKeyboardViewController
  • GridKeyboardInputViewController has been renamed to GridKeyboardViewController
  • KeyboardAlerter has been renamed to KeyboardAlert
  • ToastAlerter has been renamed to ToastAlert
  • ToastAlert now has two nested view classes View and Label
  • ToastAlert's two style function has changed signature
  • ToastAlerterAppearance is now an internal ToastAlert.Appearance struct
  • Most extensions have been made internal, to avoid exposing them externally

- 2018-10-04 21:08:37

Keyboard has been given an optional ID, which can be used to uniquely identify a keyboard. This makes it easier to manage multiple keyboards in an app.

KeyboardInputViewController implements the KeyboardPresenter protocol, which means that you can set the new optional id property to make a KeyboardSetting exclusive to that presenter. This is nice if your app has multiple keyboards. If you do not specify an id, the settings behave just like before.

A PR by micazeve is merged. It limits the current page index that is persisted for a keyboard, to avoid bugs if the page count has changed since persisting the value.