SwiftUI 和 SceneKit 如何搭配使用?
How to use SwiftUI and SceneKit together?
我在 SwiftUI 的框架内的场景中显示了一个 SCNCylinder。我想将它绕某个轴旋转 180º。在 SwiftUI 视图中按下 180º
(某种)按钮后,我希望圆柱体旋转。目前我可以旋转一次,但第二次按下按钮时它不会旋转。我尝试先将旋转角度定义为零,然后再定义为 180º,但这样做之后,整个过程在我按下按钮后就崩溃了。我只是想让圆柱体在我按下按钮后第二次旋转。
这是我的代码:
//SwiftUI view
struct ContentView: View {
@State var rotationAngle: Angle = .degrees(0)
var body: some View {
VStack{
Text("180º").onTapGesture {
self.rotationAngle = .zero
self.rotationAngle = .degrees(180)
}
}
SceneKitView(radius: 0.02, height: 2, angle: $rotationAngle)
.position(x: 200.0, y: 140)
.frame(width: 300, height: 300, alignment: .center)
}
}
}
//SceneKit View
struct SceneKitView: UIViewRepresentable {
@Binding var angle: Angle
let cylindernode: SCNNode
init(radius: CGFloat, height: CGFloat, angle: Binding<Angle>) {
let cylinder = SCNCylinder(radius: radius, height: height)
cylinder.firstMaterial?.diffuse.contents = UIColor.green
self.cylindernode = SCNNode(geometry: cylinder)
self.cylindernode.position = SCNVector3(0, 0, 0)
self.cylindernode.orientation = SCNVector4(0, 0, 0, 0)
cylindernode.pivot = SCNMatrix4MakeTranslation(0, -1, 0)
self._angle = angle
}
//SCNScene
func makeUIView(context: UIViewRepresentableContext<SceneKitView>) -> SCNView {
let sceneView = SCNView()
sceneView.scene = SCNScene()
sceneView.autoenablesDefaultLighting = true
sceneView.allowsCameraControl = true
sceneView.scene?.rootNode.addChildNode(cylindernode)
return sceneView
}
func updateUIView(_ sceneView: SCNView, context: UIViewRepresentableContext<SceneKitView>) {
//Rotation animation
let rotation = CABasicAnimation(keyPath: "transform.rotation")
rotation.isRemovedOnCompletion = false
rotation.duration = 5
cylindernode.addAnimation(rotation, forKey: "rotation")
cylindernode.rotation = SCNVector4(1, 0, 0, angle.radians)
}
}
}
删除行 self.rotationAngle = .zero
后,代码运行良好,但视图没有更新。但是,如果我保留这条线,那么在我按下按钮后,整个过程就会崩溃。
试试这个:但是因为你问了很多问题而且它们都很基础,也许你应该检查一些初级 swift 课程来学习如何设置变量......这与使用 Scenekit 和 SwiftUI - 它只是更改一个变量。
struct ContentView: View {
@State var rotationAngle: Angle = .degrees(0)
var body: some View {
VStack{
Text("180º").onTapGesture {
self.rotationAngle += .degrees(90)
print(self.rotationAngle)
}
SceneKitView(radius: 0.02, height: 2, angle: $rotationAngle)
.position(x: 200.0, y: 140)
.frame(width: 300, height: 300, alignment: .center)
}
}
}
我在 SwiftUI 的框架内的场景中显示了一个 SCNCylinder。我想将它绕某个轴旋转 180º。在 SwiftUI 视图中按下 180º
(某种)按钮后,我希望圆柱体旋转。目前我可以旋转一次,但第二次按下按钮时它不会旋转。我尝试先将旋转角度定义为零,然后再定义为 180º,但这样做之后,整个过程在我按下按钮后就崩溃了。我只是想让圆柱体在我按下按钮后第二次旋转。
这是我的代码:
//SwiftUI view
struct ContentView: View {
@State var rotationAngle: Angle = .degrees(0)
var body: some View {
VStack{
Text("180º").onTapGesture {
self.rotationAngle = .zero
self.rotationAngle = .degrees(180)
}
}
SceneKitView(radius: 0.02, height: 2, angle: $rotationAngle)
.position(x: 200.0, y: 140)
.frame(width: 300, height: 300, alignment: .center)
}
}
}
//SceneKit View
struct SceneKitView: UIViewRepresentable {
@Binding var angle: Angle
let cylindernode: SCNNode
init(radius: CGFloat, height: CGFloat, angle: Binding<Angle>) {
let cylinder = SCNCylinder(radius: radius, height: height)
cylinder.firstMaterial?.diffuse.contents = UIColor.green
self.cylindernode = SCNNode(geometry: cylinder)
self.cylindernode.position = SCNVector3(0, 0, 0)
self.cylindernode.orientation = SCNVector4(0, 0, 0, 0)
cylindernode.pivot = SCNMatrix4MakeTranslation(0, -1, 0)
self._angle = angle
}
//SCNScene
func makeUIView(context: UIViewRepresentableContext<SceneKitView>) -> SCNView {
let sceneView = SCNView()
sceneView.scene = SCNScene()
sceneView.autoenablesDefaultLighting = true
sceneView.allowsCameraControl = true
sceneView.scene?.rootNode.addChildNode(cylindernode)
return sceneView
}
func updateUIView(_ sceneView: SCNView, context: UIViewRepresentableContext<SceneKitView>) {
//Rotation animation
let rotation = CABasicAnimation(keyPath: "transform.rotation")
rotation.isRemovedOnCompletion = false
rotation.duration = 5
cylindernode.addAnimation(rotation, forKey: "rotation")
cylindernode.rotation = SCNVector4(1, 0, 0, angle.radians)
}
}
}
删除行 self.rotationAngle = .zero
后,代码运行良好,但视图没有更新。但是,如果我保留这条线,那么在我按下按钮后,整个过程就会崩溃。
试试这个:但是因为你问了很多问题而且它们都很基础,也许你应该检查一些初级 swift 课程来学习如何设置变量......这与使用 Scenekit 和 SwiftUI - 它只是更改一个变量。
struct ContentView: View {
@State var rotationAngle: Angle = .degrees(0)
var body: some View {
VStack{
Text("180º").onTapGesture {
self.rotationAngle += .degrees(90)
print(self.rotationAngle)
}
SceneKitView(radius: 0.02, height: 2, angle: $rotationAngle)
.position(x: 200.0, y: 140)
.frame(width: 300, height: 300, alignment: .center)
}
}
}