UIKeyCommandNate Cook April Peng 🚩🌱

给产品添加新功能始终是一个权衡。新功能添加的工具是否足以抵消增加的复杂性?不过快捷键似乎可以避开这个问题,毕竟,他们只是对应用程序已有的功能更快的替代方案。但是却创造了另一种困境:会不会一个新的功能被加入了却没有人知道它的存在?

在 iOS 7 里,当外部键盘发送键盘命令时,并没有直观的办法知道他们的存在。不像 OS X,用户可以在他们最常使用的菜单项中逐渐找到快捷方式,一个 iOS 应用程序很少有方法来告诉用户可用的键盘命令。初学教程总是一闪而过留不下任何记忆,帮助屏幕也总是淡出在视线之外。如果没有一种方法能及时且相关的使快捷方式可见,用户们一定会错过开发者花心思实现的非常有用的功能。

然而这种情况将不再继续了。为了使 iPad 更高效的工作,iOS 9 增加了 可发现特性,这是一个叠加层,用于显示一个应用程序内当前可用的键盘命令。在 iPad 上,这个微小的变化使得键盘命令瞬间变得比以往有用多了,并且也使得 UIKeyCommand 成为你的应用程序的一个必要的附加功能。


UIKeyCommand

UIKeyCommand 类其实很简单,只有四个属性来配置:

响应键盘命令

启用键盘命令很简单,只需要在响应链的某处提供一个 UIKeyCommand 实例的数组。文字输入是自动的第一响应者,但也许更方便的是在视图控制器通过实现 canBecomeFirstResponder() 来响应键盘命令:

override func canBecomeFirstResponder() -> Bool {
    return true
}
- (BOOL)canBecomeFirstResponder {
    return YES;
}

接下来,通过 keyCommands 属性提供可用的按键命令列表:

override var keyCommands: [UIKeyCommand]? {
    return [
        UIKeyCommand(input: "1", modifierFlags: .Command, action: "selectTab:", discoverabilityTitle: "Types"),
        UIKeyCommand(input: "2", modifierFlags: .Command, action: "selectTab:", discoverabilityTitle: "Protocols"),
        UIKeyCommand(input: "3", modifierFlags: .Command, action: "selectTab:", discoverabilityTitle: "Functions"),
        UIKeyCommand(input: "4", modifierFlags: .Command, action: "selectTab:", discoverabilityTitle: "Operators"),
            
        UIKeyCommand(input: "f", modifierFlags: [.Command, .Alternate], action: "search:", discoverabilityTitle: "Find…"),
    ]
}

// ...

func selectTab(sender: UIKeyCommand) {
    let selectedTab = sender.input
    // ...
}
- (NSArray<UIKeyCommand *>*)keyCommands {
    return @[
        [UIKeyCommand keyCommandWithInput:@"1" modifierFlags:UIKeyModifierCommand action:@selector(selectTab:) discoverabilityTitle:@"Types"],
        [UIKeyCommand keyCommandWithInput:@"2" modifierFlags:UIKeyModifierCommand action:@selector(selectTab:) discoverabilityTitle:@"Protocols"],
        [UIKeyCommand keyCommandWithInput:@"3" modifierFlags:UIKeyModifierCommand action:@selector(selectTab:) discoverabilityTitle:@"Functions"],
        [UIKeyCommand keyCommandWithInput:@"4" modifierFlags:UIKeyModifierCommand action:@selector(selectTab:) discoverabilityTitle:@"Operators"],

        [UIKeyCommand keyCommandWithInput:@"f" 
                            modifierFlags:UIKeyModifierCommand | UIKeyModifierAlternate 
                                   action:@selector(search:) 
                     discoverabilityTitle:@"Find…"]
    ];
}

// ...

- (void)selectTab:(UIKeyCommand *)sender {
    NSString *selectedTab = sender.input;
    // ...
}

按住 Command 键显示可视层,关键命令将以你指定的顺序列出:

Discoverability Layover

瞧! 秘密被发现了!

情境敏感性

只要一个按键被按下, keyCommands 属性就会被访问,从而可以提供根据你应用程序的上下文状态敏感的反应。虽然这是类似菜单项的方式,其有效/无效状态被配置在 OS X 里面,iOS 版的建议是完全忽略不活动的命令,也就是说,在发现层不要显示变灰的命令。

以下是在一个应用程序里的一套对已登录用户可用的命令:

let globalKeyCommands = [UIKeyCommand(input:...), ...]
let loggedInUserKeyCommands = [UIKeyCommand(input:...), ...]

override var keyCommands: [UIKeyCommand]? {
    if isLoggedInUser() {
        return globalKeyCommands + loggedInUserKeyCommands
    } else {
        return globalKeyCommands
    }
}

虽然我们在创建应用程序时并没有走捷径,这并不意味着用户觉得快捷方式没用。添加键盘命令可以让你的应用程序从屏幕转变到键盘,你的用户一定会喜欢新的选择。


除非另有声明,本文采用知识共享「署名-非商业性使用 3.0 中国大陆」许可协议授权。