在将SceneKit与SwiftUI一起使用时,如何访问SCNScenerEnderDelegate方法?
我通过Mehdi提供的以下解决方案将SceneKit与SwiftUI结合使用: 通常,创建SceneKit项目时,实现渲染器方法与在GameViewController文件中添加以下扩展名并实现每个渲染器方法一样简单:在将SceneKit与SwiftUI一起使用时,如何访问SCNScenerEnderDelegate方法?,swift,swiftui,scenekit,Swift,Swiftui,Scenekit,我通过Mehdi提供的以下解决方案将SceneKit与SwiftUI结合使用: 通常,创建SceneKit项目时,实现渲染器方法与在GameViewController文件中添加以下扩展名并实现每个渲染器方法一样简单: extension GameViewController: SCNSceneRendererDelegate { // 2 func renderer(renderer: SCNSceneRenderer, updateAtTime time: NSTimeInterv
extension GameViewController: SCNSceneRendererDelegate {
// 2
func renderer(renderer: SCNSceneRenderer, updateAtTime time: NSTimeInterval) {
// 3
doWhatever()
}
}
但在使用SwiftUI时,我们使用的是结构而不是类(请参见上面的链接问题),因此我们不能简单地添加扩展,因为Xcode抱怨:
Non-class type 'ScenekitView" cannot conform to class protocol 'NSObjectProtocol'
Non-class type 'ScenekitView' cannot conform to class protocol 'SCNSceneRendererDelegate'
这个问题的解决方案是什么?在以下答案中找到了解决方案: 在Andy问题的下半部分,他描述了如何使用协调器来实现委托方法。为方便起见,请在此复制:
struct ScenekitView: NSViewRepresentable {
@Binding var showStats: Bool
let sceneView = SCNView(frame: .zero)
let scene = SCNScene(named: "art.scnassets/ship.scn")!
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
final class Coordinator: NSObject, SCNSceneRendererDelegate {
var control: ScenekitView
init(_ control: ScenekitView) {
self.control = control
}
func renderer(_ renderer: SCNSceneRenderer,
updateAtTime time: TimeInterval) {
control.sceneView.showsStatistics = control.showStats
for i in 0...255 {
control.sceneView.backgroundColor = NSColor(
red: CGFloat(arc4random_uniform(UInt32(i))),
green: CGFloat(arc4random_uniform(UInt32(i))),
blue: CGFloat(arc4random_uniform(UInt32(i))),
alpha: 1.0)
}
}
}
func scnScene(stat: Bool, context: Context) -> SCNView {
sceneView.scene = scene
sceneView.showsStatistics = stat
sceneView.delegate = context.coordinator
return sceneView
}
func makeNSView(context: Context) -> SCNView {
scnScene(stat: true, context: context)
}
func updateNSView(_ uiView: SCNView, context: Context) { }
}
你对协调员的使用正是我想要的。非常感谢。