Typist is a small, drop-in Swift UIKit keyboard manager for iOS apps. It helps you manage keyboard's screen presence and behavior without notification center and Objective-C.
Declare what should happen on what event and start()
listening to keyboard events. That's it.
let keyboard = Typist.shared // use `Typist()` whenever you can, see note on singleton usage below
func configureKeyboard() {
keyboard
.on(event: .didShow) { (options) in
print("New Keyboard Frame is \(options.endFrame).")
}
.on(event: .didHide) { (options) in
print("It took \(options.animationDuration) seconds to animate keyboard out.")
}
.start()
}
You must call start()
for callbacks to be triggered. Calling stop()
on instance will stop callbacks from triggering, but callbacks themselves won't be dismissed, thus you can resume event callbacks by calling start()
again.
To remove all event callbacks, call clear()
.
You can dismiss keyboard interactively when using Typist with UIScrollView
instances.
let keyboard = Typist()
func configureKeyboard() {
keyboard
.toolbar(scrollView: tableView) // Enables interactive dismissal
.on(event: .willChangeFrame) { (options) in
// You are responsible animating inputAccessoryView
}
.on(event: .willHide) { (options) in
// Triggered when keyboard is dismissed non-interactively.
}
.start()
}
.on(event: .willChangeFrame, do: {...})
will update as frequently as keyboard frame changes due to UIScrollView scrolling. It is good practice to implement .willHide
portion as well since keyboard might be dismissed non-interactively, for example, using resignFirstResponder()
.
Example from above is implemented in demo app.
Usage of shared
singleton, considered to be OK for convenient access to instance. However, it is strongly recommended to instantiate dedicated Typist()
for each usage (in UIViewController
, most likely). Do not use singleton when two or more objects using Typist.shared
are presented on screen simultaneously, as it will cause one of the controllers to fail receiving keyboard events.
Every event callback has a parameter of Typist.KeyboardOptions
type. It is an inert/immutable struct which carries all data that keyboard has at the event of happening:
belongsToCurrentApp
—Bool
that identifies whether the keyboard belongs to the current app. With multitasking on iPad, all visible apps are notified when the keyboard appears and disappears. The value istrue
for the app that caused the keyboard to appear andfalse
for any other apps.startFrame
—CGRect
that identifies the start frame of the keyboard in screen coordinates. These coordinates do not take into account any rotation factors applied to the view’s contents as a result of interface orientation changes. Thus, you may need to convert the rectangle to view coordinates (using theconvert(CGRect, from: UIView?)
method) before using it.endFrame
—CGRect
that identifies the end frame of the keyboard in screen coordinates. These coordinates do not take into account any rotation factors applied to the view’s contents as a result of interface orientation changes. Thus, you may need to convert the rectangle to view coordinates (using theconvert(CGRect, from: UIView?)
method) before using it.animationCurve
—UIView.AnimationCurve
constant that defines how the keyboard will be animated onto or off the screen.animationDuration
—Double
that identifies the duration of the animation in seconds.animationOptions
—UIView.AnimationOptions
helper property that maps theanimationCurve
to its respectiveUIView.AnimationOptions
value. Usefull when performming view animations usingUIView.animate(...
.
Following keyboard events are supported:
willShow
didShow
willHide
didHide
willChangeFrame
didChangeFrame
– e.g. when keyboard is dynamically dismissed from scroll view interaction.
If you declare two closures on same event, only latter will be executed.
You can use CocoaPods to install Typist
by adding it to your Podfile
:
platform :ios, '8.0'
use_frameworks!
pod 'Typist'
Import Typist
wherever you plan to listen to keyboard events. Usually in your UIViewController
subclasses.
import UIKit
import Typist
Create a Cartfile
that lists the framework and run carthage update
. Follow the instructions to add $(SRCROOT)/Carthage/Build/iOS/Typist.framework
to an iOS project.
github "totocaster/Typist"
Initialize your project with Accio using the init
command.
Add the following to your Package.swift:
.package(url: "https://github.com/totocaster/Typist.git", .upToNextMajor(from: "1.4.2")),
Next, add Typist
to your App targets dependencies like so:
.target(
name: "App",
dependencies: [
"Typist",
]
),
Then run accio update
.
Download and drop Typist.swift
in your project.
My thanks to Jake Marsh for featuring Typist on Little Bites of Cocoa #282: Taming the Keyboard with Typist ⌨️. It made my day.
Typist is released under the MIT license. See LICENSE
for details.