【问题标题】:How to access SCNSceneRendererDelegate methods when using SceneKit with SwiftUI?将 SceneKit 与 SwiftUI 一起使用时如何访问 SCNSceneRendererDelegate 方法?
【发布时间】:2020-07-08 20:16:49
【问题描述】:

我正在使用带有 SwiftUI 的 SceneKit,遵循 Mehdi 为这个问题提供的解决方案:

SwiftUI - how to add a Scenekit Scene

通常,当创建一个 SceneKit 项目时,实现渲染器方法就像在 GameViewController 文件中添加以下扩展并实现每个渲染器方法一样简单:

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'

解决办法是什么?

【问题讨论】:

    标签: swift swiftui scenekit


    【解决方案1】:

    在这个答案中找到了解决方案:

    SwiftUI – Passing data from SwiftUIView to SceneKit

    在 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) { }
    }
    

    【讨论】:

    • 您对协调器的使用正是我想要的。谢谢。
    猜你喜欢
    • 2020-04-13
    • 1970-01-01
    • 2016-05-25
    • 2014-08-13
    • 1970-01-01
    • 2017-09-04
    • 2020-04-05
    • 1970-01-01
    • 2020-11-13
    相关资源
    最近更新 更多