I have a small start on a SwiftUI app. I'm trying to connect a button to an action in an NSView that I've added to the body of the SwiftUI.
I can't figure out how to reference the DrawingView inside the action of the button so that I can call the toggleDrawingType action. I've found no developer documentation that gives any hints as to how to go about this.
------- 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)
}
}
I had the same problem and found a solution in the organisation of the code.
The basic problem is that a structure following the NSViewRepresentable protocol does by itself not hand out a reference to its underlying NSView.
The solution is to introduce an object which is available at the time of creation of the ViewRepresentable structure. Its reference to the view is set at the time of creation of the view.
I my eyes this is part of the bigger picture that with SwiftUI views view controllers are not any longer present. SwiftUI views depend directly on the model objects (via the @ObservableObject or @EnvironmentObject variable). Hence the model object tends to cary the functionality which before the view controller carried (or the View structure carries this functionality directly).
I hand in the model object into the initialiser of the ViewRepresentable and set a weak reference within the model object to the view created. Like this the content object is the omnipresent entity - within the ViewRepresentable and within the SwiftUI View structure.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.