I am curious how to interface with Metal shaders. The above MetalView code provided by the Graphics & Games engineer works, and works when I implement the Coordinator class in a separate file.
The issue I'm having seems to be when we set the mtkView delegate:
func makeUIView(context: UIViewRepresentableContext<MetalMapView>) -> MTKView {
mtkView.delegate = context.coordinator
...
}
because (see MakeCoordinator() https://developer.apple.com/documentation/swiftui/nsviewrepresentable/makecoordinator()-9e4i4 )
SwiftUI calls this method before calling the makeUIView(context:) method. (of course the same is also true in the case of NSViewRepresentable, makeNSView )
My Coordinator class is just a renderer of sorts, and during initialization requires an MTKView. This is where I am having trouble. I am unsure of how (or where?) to create an MTKView for passing to my Coordinator / MTKViewDelegate. For example, in my Coordinator class, I attempt to obtain the aspect ratio by
var aspect = Float(mtkView.drawableSize.width / mtkView.drawableSize.height)
which returns NaN or some equivalent nonsense. I guess I do not have a properly initialized MTKView or something, I am not entirely sure how or where to do this (disclaimer: I am still fairly new to Metal and Swift programming). Furthermore, I do not know where I should be storing the MTKView -- should it be as @State or @Environment? Should it not be stored or initialized inside the MetalView struct?
I do not have issues when I do the same thing in a non-SwiftUI setup, e.g. in
class ViewController: UIViewController {
var mtkView: MTKView!
...
override func viewDidLoad() {
super.viewDidLoad()
guard let mtkViewTemp = self.view as? MTKView else {...}
mtkView = mtkViewTemp
...
}
and as far as I know making the (naive, speaking for myself) switch from UIViewRepresentable to UIViewControllerRepresentable is not a fix. As I stated a few lines above, the issue seems to be with how I am attempting to create, store, and use the MTKView.
Topic:
UI Frameworks
SubTopic:
SwiftUI
Tags: