实现Markdown文本编辑器.

每行文本都是一个TextField.

需要切换?和?上的线路

First attempt:

TextField(...)
 .onKeyPress(.downArrow) {
    print("down")
    return .handled
 }

此事件永远不会触发

Second attempt:

import SwiftUI

class CustomTextField: NSTextField {
    override public var acceptsFirstResponder: Bool { true }
    
    override func keyDown(with event: NSEvent) {
        print("key down with character: \(String(describing: event.characters)) " )
        super.keyDown(with: event)
    }
}

struct LineEditor: NSViewRepresentable {
    @Binding var text: String
    
    init(_ text: Binding<String>) {
        self._text = text
    }
    
    typealias NSViewType = CustomTextField
    
    func makeNSView(context: Context) -> CustomTextField {
        let view = CustomTextField(string: text)
        view.delegate = context.coordinator
        return view
    }
    
    func updateNSView(_ nsView: CustomTextField, context: Context) {
        nsView.stringValue = text
    }
    
    class Coordinator: NSObject, NSTextFieldDelegate {
        var parent: LineEditor
        
        init(_ parent: LineEditor) {
            self.parent = parent
        }
        
        func controlTextDidChange(_ obj: Notification) {
            let field = obj.object as! NSTextField
            self.parent.text = field.stringValue
        }
    }
    
    func makeCoordinator() -> Coordinator {
        return Coordinator(self)
    }
}

keyDown也从来不会被称为keyDown.

Question:如何在现代SwiftUI中正确跟踪按键事件?

推荐答案

不知道这是不是最好的/唯一的方法,但是添加一个隐藏的按钮,并为你想要处理的每个键绑定一个键盘快捷键,怎么样?

例如:

TextField("", text: $text)
    .background {
        ZStack {
            Button("") {
                print("TODO: focus previous field")
            }
            .keyboardShortcut(KeyboardShortcut(.upArrow, modifiers: []))

            Button("") {
                print("TODO: focus next field")
            }
            .keyboardShortcut(KeyboardShortcut(.downArrow, modifiers: []))
        }
        .opacity(0)
    }

注意:空修饰符数组(modifiers: [])很重要,因为快捷键也需要命令键.

Swift相关问答推荐

动画过程中的SwiftUI重绘视图

RealityKit如何获得两个相对大小相同的ModelEntity?

减go 用SWIFT struct 填充的NSCountedSet

如何在SWIFT任务中判断当前任务是否已取消(异步/等待)

了解SWIFT中的命名VS位置函数调用

从Firebase播放音频文件不起作用

NavigationLink和ObservableObject的动画片段

如何避免切换视图递归onChange调用SwiftUI

在扩展中创建通用排序函数

如何使用Swift宏和@Observable和@Environment?

SwiftUI .task 视图修改器:运行在哪个线程中?

如何在SwiftUI中更改NSTextView中的 Select colored颜色 ?

(Swift)混淆了函数内 for-in 循环的返回值和循环后(函数内)的返回值)

类型擦除`AsyncMapSequence, Element>`

RxSwift 提高性能

如何在 SwiftUI 中通过按钮点击一次为一个更改设置动画?

Swift 中的 PageViewController 当前页面索引

Swift - 导入我的 swift 类

不能从非开放类继承 swift

快速延迟加载属性