使用 UIKeyCommand 映射键盘快捷键呈现 UITextField/View 无用

Using UIKeyCommand to map keyboard shortcuts renders UITextField/View useless

我正在使用 UIKeyCommand 将某些快捷方式(例如 "b"、箭头键、"t"、"p" 等)映射到我的功能中UIViewController 子类。该应用程序是一种矢量图形软件,允许在 canvas 内添加文本对象。编辑视图控制器内的 textView 或 textField 时会出现问题。当它获得第一响应者状态时,它不会收到快捷键(例如写入 "beaver" 将导致 "eaver")。

是否有正确的方法来处理快捷键并在单个视图控制器中使用文本对象?

我发现最有效的解决方案是通过响应链找到活动响应者,然后检查它是否是 UITextField/UITextView 或其他。如果是,return nil 来自 - (NSArray *)keyCommands 方法,否则 return 快捷方式。 这是代码本身:

@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];
}

如果视图控制器(具有快捷方式 keyCommands)不是第一响应者,我的解决方案是覆盖 canPerformAction:withSender: 和 return false。这使得沿着响应者链的遍历无法找到接受键盘命令的目标,而是将按键发送给第一响应者作为正常的 UIKeyInput 并且该字符出现在文本字段中。例如

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender{
    if(action == @selector(brushKeyCommand:)){
        return self.isFirstResponder;
    }
    return [super canPerformAction:action withSender:sender];
}