将数据从简单的 NSView 传递到 SwiftUI 视图

Posted

技术标签:

【中文标题】将数据从简单的 NSView 传递到 SwiftUI 视图【英文标题】:Passing data from simple NSView to SwiftUI View 【发布时间】:2020-05-16 06:17:53 【问题描述】:

我正在使用 SwiftUI 制作一个 macOS 应用程序。我有一个符合NSViewRepresentable 的结构,其目的是检测按下哪个键的键码。我想将event.keyCode 传递回 SwiftUI 并将其保存到环境对象中,这样我就可以在我的应用程序的其他地方使用关键代码。 我知道我应该使用 SwiftUI 协调器,但我能找到的所有教程和 Stack Overflow 问题都使用现成的类,例如 UIPageControlUISearchBar 具有预先配置的委托。我不确定使用简单的自定义NSView 时该怎么做。有人可以解释在使用自定义NSView 时如何将NSViewRepresentable 结构中的数据传递到我的@EnvironmentObject 中吗?

struct KeyboardEvent: NSViewRepresentable 

    class KeyView: NSView 
        override var acceptsFirstResponder: Bool  true 
        override func keyDown(with event: NSEvent) 
            print("\(event.keyCode)")
        
    

    func makeNSView(context: Context) -> NSView 
        let view = KeyView()
        DispatchQueue.main.async 
            view.window?.makeFirstResponder(view)
        
        return view
    

    func updateNSView(_ nsView: NSView, context: Context) 
    



struct ContentView: View 
    @EnvironmentObject var input: KeyboardInput     // save the keyCode here
    var body: some View 
        VStack 
            Text(input.keyCode)
            KeyboardEvent()
        
    

现在它正常将关键代码打印到 Xcode 控制台,因此检测工作正常。

【问题讨论】:

顺便说一句,我知道这个问题非常简单,但我对应用程序开发很陌生,而且我已经坚持了好几天了,所以感谢您的帮助! 【参考方案1】:

这是一个解决方案(有一些复制的部分)。使用 Xcode 11.4 / macOS 10.15.4 测试

class KeyboardInput: ObservableObject 
    @Published var keyCode: UInt16 = 0


struct KeyboardEvent: NSViewRepresentable 
    @Binding var keyStorage: UInt16          // << here !!
    init(into storage: Binding<UInt16>) 
        _keyStorage = storage
    

    class KeyView: NSView 
        var owner: KeyboardEvent?   // << view holder

        override var acceptsFirstResponder: Bool  true 
        override func keyDown(with event: NSEvent) 
            print("\(event.keyCode)")
            owner?.keyStorage = event.keyCode
        
    

    func makeNSView(context: Context) -> NSView 
        let view = KeyView()
        view.owner = self           // << inject
        DispatchQueue.main.async 
            view.window?.makeFirstResponder(view)
        
        return view
    

    func updateNSView(_ nsView: NSView, context: Context) 
    



struct ContentView: View 
    @EnvironmentObject var input: KeyboardInput     // save the keyCode here
    var body: some View 
        VStack 
            Text("Code: \(input.keyCode)")
            KeyboardEvent(into: $input.keyCode) // << binding !!!
        
    

【讨论】:

以上是关于将数据从简单的 NSView 传递到 SwiftUI 视图的主要内容,如果未能解决你的问题,请参考以下文章

从简单的 python 列表创建图像和标签的 tensorflow 数据集

Scala Spark - 从简单的数据框创建嵌套的 json 输出

Jquery datatable 在从简单的 Web 服务调用 Web 方法时未在表中显示任何数据

从简单的 XML 文件中提取数据

如何从简单的 Python 服务器打印到 html 页面?

从简单的图像 ios 创建贝塞尔路径