如何将 swiftUI 按钮连接到 NSView 操作?

Posted

技术标签:

【中文标题】如何将 swiftUI 按钮连接到 NSView 操作?【英文标题】:How to connect a swiftUI button to an NSView action? 【发布时间】:2019-06-08 21:12:15 【问题描述】:

我有一个 SwiftUI 应用程序的小开始。我正在尝试将按钮连接到已添加到 SwiftUI 主体的 NSView 中的操作。

我不知道如何在按钮的操作中引用 DrawingView,以便我可以调用 toggleDrawingType 操作。我没有发现任何开发人员文档可以提供有关如何进行此操作的任何提示。

------- ContentView.swift -------
import SwiftUI

struct ContentView : View 
    var body: some View 
        VStack 
            HStack 
                Text("Hello")
                Image("LineTool")
                Button(action: ) 
                    Image("CenterCircleTool")
                
            
            DrawingView()
        
    


-------- DrawingView.swift --------

import SwiftUI

public struct DrawingView: NSViewRepresentable 
    public typealias NSViewType = DrawingViewImplementation

    public func makeNSView(context: NSViewRepresentableContext<DrawingView>) -> DrawingViewImplementation 
        return DrawingViewImplementation()
    

    public func updateNSView(_ nsView: DrawingViewImplementation, context: NSViewRepresentableContext<DrawingView>) 
        nsView.setNeedsDisplay(nsView.bounds)
    


enum DrawingType 
    case Rect
    case Circle


public class DrawingViewImplementation: NSView 

    var currentType = DrawingType.Rect

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

        NSColor.blue.set()
        switch currentType 
        case .Rect:
            NSRect(x: 100, y: 100, width: 100, height: 100).frame()
        case .Circle:
            NSBezierPath(ovalIn: NSRect(x: 100, y: 100, width: 100, height: 100)).stroke()
        
    

    @IBAction func toggleDrawingType(sender: Any) 
        switch currentType 
        case .Rect:
            currentType = .Circle
        case .Circle:
            currentType = .Rect
        
        setNeedsDisplay(bounds)
   

    public override func mouseDown(with event: NSEvent) 
        toggleDrawingType(sender: self)
    

【问题讨论】:

【参考方案1】:

我遇到了同样的问题,并在代码组织中找到了解决方案。

基本问题是遵循 NSViewRepresentable 协议的结构本身并不会分发对其底层 NSView 的引用。

解决方案是引入一个在创建 ViewRepresentable 结构时可用的对象。它对视图的引用是在创建视图时设置的。

在我看来,这是 SwiftUI 视图视图控制器不再存在的大局的一部分。 SwiftUI 视图直接依赖于模型对象(通过@ObservableObject 或@EnvironmentObject 变量)。因此,模型对象倾向于承载视图控制器之前承载的功能(或视图结构直接承载此功能)。

我将模型对象提交给 ViewRepresentable 的初始化程序,并在模型对象中设置对创建的视图的弱引用。像这样,内容对象是无所不在的实体——在 ViewRepresentable 和 SwiftUI 视图结构中。

【讨论】:

以上是关于如何将 swiftUI 按钮连接到 NSView 操作?的主要内容,如果未能解决你的问题,请参考以下文章

将 UIViewRepresentable 连接到 SwiftUI

导入SwiftUI时如何使NSView与CALayerDelegate兼容?

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

从 viewcontrollernib 加载 NSView

将数据从简单的 NSView 传递到 SwiftUI View:即 event.keyCode 案例

我无法将 TableViewCell 按钮连接到 TableViewController!如何将 TableViewCell 中的值连接到 TableViewController?