UIKeyCommand
Adding a new feature to a product is always a tradeoff. Will the added utility of a new feature be enough to offset the added complexity? Shortcuts would seem to side-step this issue—after all, they’re simply a quicker alternative for features already in your app. But that creates another dilemma: what if a new feature is added and no one knows it’s there?
When key commands for external keyboards debuted in iOS 7, there was no intrinsic way to learn of their existence. Unlike in OS X, where a user can gradually discover shortcuts for the menu items they use most often, an iOS app had few ways to communicate what key commands are available. Initial tours flash by and fade from memory; help screens are hidden out of sight. Without a way to make shortcuts visible in a timely and relevant manner, users were sure to miss out on useful features that developers had taken the time to implement.
No longer. As part of the push for greater productivity on the iPad, iOS 9 adds Discoverability, an overlay showing the currently available key commands inside an app. This small change suddenly makes key commands far more viable on the iPad and, with it, makes UIKey
a necessary addition to your app.
UIKey Command
The UIKey
class is in fact quite simple, with only four properties to configure:
-
input
: The character of the key you’d like to recognize, or the correct constant for the arrow and escape keys, which do not have characters themselves. The available constants are:UIKey
Input Up Arrow UIKey
Input Down Arrow UIKey
Input Left Arrow UIKey
Input Right Arrow UIKey
Input Escape
-
modifier
: One or moreFlags UIKey
, describing the modifier keys that should be pressed in combination withModifier Flags input
:-
.Command
,.Alternate
,.Shift
,.Control
: The Command, Option, Shift, and Control keys, respectively. -
.Numeric
: Indicates thatPad input
should come from the numeric keypad rather than the top row of the standard keyboard. -
.Alpha
: Indicates that the CapsLock key should be pressed as part of the combination, rather than just engaged.Shift
-
-
action
: The selector to call when the key command is invoked, called with aUIKey
as its only argument. The key event will travel up the responder chain until a matching selector is found.Command -
discoverability
(iOS 9 only): An optional label to display for the key command in the Discoverability layover. Only key commands with a title set will be listed.Title
Responding to Key Commands
Enabling key commands is as simple as providing an array of UIKey
instances somewhere in the responder chain. Text inputs are automatically first responders, but perhaps more usefully, a view controller can respond to key commands by implementing can
:
override func can Become First Responder() -> Bool {
return true
}
- (BOOL)can Become First Responder {
return YES;
}
Next, provide a list of available key commands via the key
property:
override var key Commands: [UIKey Command]? {
return [
UIKey Command(input: "1", modifier Flags: .Command, action: "select Tab:", discoverability Title: "Types"),
UIKey Command(input: "2", modifier Flags: .Command, action: "select Tab:", discoverability Title: "Protocols"),
UIKey Command(input: "3", modifier Flags: .Command, action: "select Tab:", discoverability Title: "Functions"),
UIKey Command(input: "4", modifier Flags: .Command, action: "select Tab:", discoverability Title: "Operators"),
UIKey Command(input: "f", modifier Flags: [.Command, .Alternate], action: "search:", discoverability Title: "Find…"),
]
}
…
func select Tab(sender: UIKey Command) {
let selected Tab = sender.input
…
}
- (NSArray<UIKey Command *>*)key Commands {
return @[
[UIKey Command key Command With Input:@"1" modifier Flags:UIKey Modifier Command action:@selector(select Tab:) discoverability Title:@"Types"],
[UIKey Command key Command With Input:@"2" modifier Flags:UIKey Modifier Command action:@selector(select Tab:) discoverability Title:@"Protocols"],
[UIKey Command key Command With Input:@"3" modifier Flags:UIKey Modifier Command action:@selector(select Tab:) discoverability Title:@"Functions"],
[UIKey Command key Command With Input:@"4" modifier Flags:UIKey Modifier Command action:@selector(select Tab:) discoverability Title:@"Operators"],
[UIKey Command key Command With Input:@"f"
modifier Flags:UIKey Modifier Command | UIKey Modifier Alternate
action:@selector(search:)
discoverability Title:@"Find…"]
];
}
…
- (void)select Tab:(UIKey Command *)sender {
NSString *selected Tab = sender.input;
…
}
In the Discoverability layover, accessed by holding down the Command key, key commands are listed in the order you specified:
Voila! Secrets, revealed!
Context Sensitivity
The key
property is accessed whenever a key pressed, making it possible to provide context-sensitive responses depending on the state of your application. While this is similar to the way a menu item and its active/inactive state are configured in OS X, the recommendation for iOS is to omit inactive commands completely—that is, there are no grayed out commands in the Discoverability layover.
Here, a set of commands that are available to logged in users of an app are included only when appropriate:
let global Key Commands = [UIKey Command(input:...), ...]
let logged In User Key Commands = [UIKey Command(input:...), ...]
override var key Commands: [UIKey Command]? {
if is Logged In User() {
return global Key Commands + logged In User Key Commands
} else {
return global Key Commands
}
}
Although we don’t take shortcuts when creating our apps, that doesn’t mean our users won’t find shortcuts useful. Adding key commands lets control of your app shift from the screen to the keyboard—your users will love the option.