【问题标题】:How to update a SceneKit scene with SwiftUI?如何使用 SwiftUI 更新 SceneKit 场景?
【发布时间】:2020-04-06 16:06:11
【问题描述】:

我在 SceneKit 的 SCNScene 中有一个作为 SCNCylinder 的圆柱体,并希望在 SwiftUI 的框架中显示它。我的目标是将圆柱体旋转 180° 或 90°(由用户选择)。为了获取(旋转角度的)输入,我在 SwiftUI 中使用了 Text()onTapGesture{ .... } 属性。点击文本后,圆柱体旋转,但现在我有两个圆柱体,一个在原始位置,一个以所需角度旋转。我不确定为什么会这样。我希望同一个圆柱体旋转,而不是相同的副本。我已经使用@State@Binding 连接了SwiftUI 视图和SceneKit 视图。

这是我的代码:

struct ContentView: View {
 @State var rotationAngle = 0

var body: some View {

    VStack{

        Text("180°").onTapGesture {
            self.rotationAngle = 180
        }

        Spacer()

        Text("90°").onTapGesture {
            self.rotationAngle = 90
        }

        SceneKitView(angle: $rotationAngle)
            .position(x: 225.0, y: 200)
            .frame(width: 300, height: 300, alignment: .center)

    }
  }
}

struct SceneKitView: UIViewRepresentable {

 @Binding var angle: Int

func degreesToRadians(_ degrees: Float) -> CGFloat {
    return CGFloat(degrees * .pi / 180)
}

func makeUIView(context: UIViewRepresentableContext<SceneKitView>) -> SCNView {

    let sceneView = SCNView()
    sceneView.scene = SCNScene()
    sceneView.allowsCameraControl = true
    sceneView.autoenablesDefaultLighting = true
    sceneView.backgroundColor = UIColor.white
    sceneView.frame = CGRect(x: 0, y: 10, width: 0, height: 1)

    return sceneView
}

func updateUIView(_ sceneView: SCNView, context: UIViewRepresentableContext<SceneKitView>) {

        let cylinder = SCNCylinder(radius: 0.02, height: 2.0)
        let cylindernode = SCNNode(geometry: cylinder)
        cylindernode.position = SCNVector3(x: 0, y: 0, z: 0)
        cylinder.firstMaterial?.diffuse.contents = UIColor.green

        cylindernode.pivot = SCNMatrix4MakeTranslation(0, -1, 0)

        let inttofloat = Float(self.angle)

         let rotation = SCNAction.rotate(by: self.degreesToRadians(inttofloat), around: SCNVector3(1, 0, 0), duration: 5)

         cylindernode.runAction(rotation)

         sceneView.scene?.rootNode.addChildNode(cylindernode)

}
typealias UIViewType = SCNView

}

我想以给定的角度进行单缸旋转。

【问题讨论】:

  • 如果您可以将正确答案标记为“正确答案”或在答案不够好时发表评论,那就太好了 - 我只是看到您问了很多问题,但从不“说”感谢您投票或给予正确的答案投票......
  • 感谢您的建议。以后我会考虑这样做的。

标签: rotation swiftui scenekit


【解决方案1】:

问题是,updateUIView 会被多次调用。您可以通过在此处添加调试点来检查这一点。因此,您的气缸将被添加多次。因此,您可以通过多种方式解决此问题...一种方法是在开始动画之前删除场景视图中的所有节点,如下所示:

func updateUIView(_ sceneView: SCNView, context: UIViewRepresentableContext<SceneKitView>) {

    sceneView.scene?.rootNode.enumerateChildNodes { (node, stop) in
        node.removeFromParentNode()
    }

【讨论】:

    猜你喜欢
    • 2019-11-06
    • 2020-03-31
    • 1970-01-01
    • 1970-01-01
    • 2018-01-29
    • 2020-08-25
    • 2016-08-02
    • 2020-09-07
    • 2020-02-02
    相关资源
    最近更新 更多