万年素人からHackerへの道

万年素人がHackerになれるまで殴り書きするぜ。

Swift3 コピペ可能なNSTextField

NSTextFieldで定義したやつはコピペできない・・・。

例えばこんなコード。

        let urlField = NSTextField()
        urlField.frame = NSRect(x: 0, y: 0, width: 300, height: 20)
        urlField.lineBreakMode = NSLineBreakMode.byTruncatingHead
        urlField.usesSingleLineMode = true
        // do something

一応探すとperformKeyEquivalentをオーバーライドして各イベントでコピペ用のコードを実装するっぽい。 Swift2のコードがあった。

    override func performKeyEquivalent(event: NSEvent) -> Bool {

ではなく、withをつけないとダメッっぽい。

・コピペできるNSTextFieldの継承クラス全コード

class Editing: NSTextField {
    private let commandKey = NSEventModifierFlags.command.rawValue
    private let commandShiftKey = NSEventModifierFlags.command.rawValue | NSEventModifierFlags.shift.rawValue

    override func performKeyEquivalent(with event: NSEvent) -> Bool {
        if event.type == NSEventType.keyDown {
            if (event.modifierFlags.rawValue &
                NSEventModifierFlags.deviceIndependentFlagsMask.rawValue) == commandKey {
                switch event.charactersIgnoringModifiers! {
                case "x":
                    if NSApp.sendAction(#selector(NSText.cut(_:)), to:nil, from:self) { return true }
                case "c":
                    if NSApp.sendAction(#selector(NSText.copy(_:)), to:nil, from:self) { return true }
                case "v":
                    if NSApp.sendAction(#selector(NSText.paste(_:)), to:nil, from:self) { return true }
                case "z":
                    if NSApp.sendAction(Selector(("undo:")), to:nil, from:self) { return true }
                case "a":
                    if NSApp.sendAction(#selector(NSResponder.selectAll(_:)), to:nil, from:self) { return true }
                default:
                    break
                }
            }
            else if (event.modifierFlags.rawValue & NSEventModifierFlags.deviceIndependentFlagsMask.rawValue) == commandShiftKey {
                if event.charactersIgnoringModifiers == "Z" {
                    if NSApp.sendAction(Selector(("redo:")), to:nil, from:self) { return true }
                }
            }
        }
        return super.performKeyEquivalent(with: event)
    }
}

こう使う。

        let urlField = Editing()
        urlField.frame = NSRect(x: 0, y: 0, width: 300, height: 20)
        urlField.lineBreakMode = NSLineBreakMode.byTruncatingHead
        urlField.usesSingleLineMode = true
        // do something

詳解Swift 第3版

詳解Swift 第3版