美文网首页
NSTextField响应键盘快捷键

NSTextField响应键盘快捷键

作者: 本帅不良 | 来源:发表于2020-09-07 17:34 被阅读0次

本文章介绍主要介绍 NSTextField对键盘事件的响应,比如复制粘贴全选拷贝等。

分类方式实现

NSTextField+KBCopy.h文件

#import <Cocoa/Cocoa.h>

NS_ASSUME_NONNULL_BEGIN

@interface NSTextField (KBCopy)

@end

NS_ASSUME_NONNULL_END

NSTextField+KBCopy.m文件

#import "NSTextField+KBCopy.h"

@implementation NSTextField (KBCopy)

//此处与网易有道词典冲突,修复
- (BOOL)performKeyEquivalent:(NSEvent *)event
{
    if (([event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask) == NSEventModifierFlagCommand) {
        // The command key is the ONLY modifier key being pressed.
        if ([[event charactersIgnoringModifiers] isEqualToString:@"x"]) {
            return [NSApp sendAction:@selector(cut:) to:[[self window] firstResponder] from:self];
        } else if ([[event charactersIgnoringModifiers] isEqualToString:@"c"]) {
            return [NSApp sendAction:@selector(copy:) to:[[self window] firstResponder] from:self];
        } else if ([[event charactersIgnoringModifiers] isEqualToString:@"v"]) {
            return [NSApp sendAction:@selector(paste:) to:[[self window] firstResponder] from:self];
        } else if ([[event charactersIgnoringModifiers] isEqualToString:@"a"]) {
            return [NSApp sendAction:@selector(selectAll:) to:[[self window] firstResponder] from:self];
        }
    }
    return [super performKeyEquivalent:event];

}

@end

直到我忽然间发现一个 bug:与网易有道词典的划线查单词功能冲突,然后发现冲突的是Command+C等快捷键。
后来我看到一篇文章说:performKeyEquivalent重写是苹果不推荐这样做的。

新的实现方式

首先,让我们看看 NSTextField的继承方式:

NSSTextField 继承自 NSControl,NSControl继承自 NSView。NSView 中有performKeyEquivalent方法。

performKeyEquivalent即为我们苦苦寻找的那个"她"

import Cocoa

class KeyEventTextField: NSTextField {
    
    private let commandKey = NSEvent.ModifierFlags.command.rawValue

    override func draw(_ dirtyRect: NSRect) {
        super.draw(dirtyRect)

        // Drawing code here.
    }
    
    override func performKeyEquivalent(with event: NSEvent) -> Bool {
        
        if (event.modifierFlags.rawValue & event.modifierFlags.intersection(.deviceIndependentFlagsMask).rawValue == commandKey){
          switch event.charactersIgnoringModifiers! {
          case "x":
            NSApp.sendAction(#selector(NSText.cut(_:)), to:nil, from:self)
          case "c":
            NSApp.sendAction(#selector(NSText.copy(_:)), to:nil, from:self)
          case "v":
            NSApp.sendAction(#selector(NSText.paste(_:)), to:nil, from:self)
          case "z":
            NSApp.sendAction(Selector(("undo:")), to:nil, from:self)
          case "a":
            NSApp.sendAction(#selector(NSStandardKeyBindingResponding.selectAll(_:)), to:nil, from:self)
          default:
            break
          }
        }
        
        
        return true
    }
    
}

如上代码,我们写了一个NSTextField 的子类,重写performKeyEquivalent方法,用于处理键盘事件。

接下来,我们一起解读下这段简单的代码:

  • 首先我们来看判断条件,大致的意思是判断我们有没有按辅助键,辅助键是否是 command
  • 接下来判断我们按的字母键是哪个,并执行对应的操作。

用法就超级简单的,只实例化我们的子类(本例为KeyEventTextField)即可。
如果是在 XIB中,则修改 class 即可:

image.png

总结:

  • 键盘事件是 NSView 的performKeyEquivalent方法中处理的,所以不仅仅是 NSTextField,NSButton 等继承自 NSView 的类皆可使用此方法处理键盘快捷键。
  • 不建议用分类实现,可能有未知 bug。

相关文章

网友评论

      本文标题:NSTextField响应键盘快捷键

      本文链接:https://www.haomeiwen.com/subject/gidlektx.html