【问题标题】:Using UIKeyCommand to map keyboard shortcuts renders UITextField/View useless使用 UIKeyCommand 映射键盘快捷键使 UITextField/View 无用
【发布时间】:2016-09-18 13:40:33
【问题描述】:
我正在使用UIKeyCommand 将某些快捷方式(例如“b”、箭头键、“t”、“p”等)映射到我的UIViewController 子类中的功能。该应用程序是一种矢量图形软件,允许在画布内添加文本对象。当正在编辑视图控制器内的 textView 或 textField 时,就会出现问题。当它获得第一响应者状态时,它不接收快捷键(例如写“beaver”将导致“eaver”)。
是否有正确的方法来处理快捷键和在单个视图控制器中使用文本对象?
【问题讨论】:
标签:
ios
objective-c
keyboard
uikit
keyboard-shortcuts
【解决方案1】:
我发现效果最好的解决方案是通过响应者链找到活动响应者,然后检查它是否是UITextField/UITextView 或其他东西。如果是,则从 - (NSArray *)keyCommands 方法返回 nil,否则返回快捷方式。
这是代码本身:
@implementation UIResponder (CMAdditions)
- (instancetype)cm_activeResponder {
UIResponder *activeResponder = nil;
if (self.isFirstResponder) {
activeResponder = self;
} else if ([self isKindOfClass:[UIViewController class]]) {
if ([(UIViewController *)self parentViewController]) {
activeResponder = [[(UIViewController *)self parentViewController] cm_activeResponder];
}
if (!activeResponder) {
activeResponder = [[(UIViewController *)self view] cm_activeResponder];
}
} else if ([self isKindOfClass:[UIView class]]) {
for (UIView *subview in [(UIView *)self subviews]) {
activeResponder = [subview cm_activeResponder];
if (activeResponder) break;
}
}
return activeResponder;
}
@end
这在 keyCommands 方法中:
- (NSArray *)keyCommands {
if ([self.cm_activeResponder isKindOfClass:[UITextView class]] || [self.cm_activeResponder isKindOfClass:[UITextField class]]) {
return nil;
}
UIKeyCommand *brushTool = [UIKeyCommand keyCommandWithInput:@"b"
modifierFlags:kNilOptions
action:@selector(brushToolEnabled)
discoverabilityTitle:NSLocalizedString(@"Brush tool", @"Brush tool")];
UIKeyCommand *groupKey = [UIKeyCommand keyCommandWithInput:@"g"
modifierFlags:UIKeyModifierCommand
action:@selector(groupKeyPressed)
discoverabilityTitle:NSLocalizedString(@"Group", @"Group")];
UIKeyCommand *ungroupKey = [UIKeyCommand keyCommandWithInput:@"g"
modifierFlags:UIKeyModifierCommand|UIKeyModifierShift
action:@selector(ungroupKeyPressed)
discoverabilityTitle:NSLocalizedString(@"Ungroup", @"Ungroup")];
return @[groupKey, ungroupKey, brushTool];
}
【解决方案2】:
如果视图控制器(具有快捷方式 keyCommands)不是第一响应者,我的解决方案是覆盖 canPerformAction:withSender: 并返回 false。这使得在响应者链中的遍历未能成功找到接受键盘命令的目标,而是将按键作为正常的UIKeyInput 发送给第一响应者,并且字符出现在文本字段中。例如
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender{
if(action == @selector(brushKeyCommand:)){
return self.isFirstResponder;
}
return [super canPerformAction:action withSender:sender];
}