如何在SwiftUI的SceneView中实现3D物体水平旋转
在SwiftUI中实现SceneView物体的水平旋转
要在SwiftUI中实现类似UIKit里的拖拽旋转效果,你可以用SwiftUI原生的DragGesture替代UIPanGestureRecognizer,结合状态变量记录当前旋转角度,具体实现如下:
1. 准备状态变量与节点引用
先定义状态变量保存当前Y轴旋转角度,同时提前获取要旋转的SceneKit节点引用:
import SwiftUI import SceneKit struct ObjectRotationView: View { @State private var scene: SCNScene? = SCNScene(named: "yourModel.scn") // 保存当前Y轴旋转角度 @State private var currentAngleY: Float = 0.0 // 目标旋转节点(可替换为你需要旋转的物体节点) @State private var targetNode: SCNNode? init() { // 初始化时获取目标节点,示例为rootNode,可改为指定名称节点 self.targetNode = scene?.rootNode // 如果是指定名称节点,用下面的代码: // self.targetNode = scene?.rootNode.childNode(withName: "TargetObject", recursively: true) } var body: some View { SceneView( scene: scene, pointOfView: cameraNode, options: [.autoenablesDefaultLighting] ) .gesture(rotationGesture) } // 定义拖拽旋转手势 private var rotationGesture: some Gesture { DragGesture() .onChanged { value in // 将水平拖拽距离转换为旋转角度,系数可调整灵敏度 let translationX = Float(value.translation.width) let angleDelta = translationX * .pi / 180 let newAngle = currentAngleY + angleDelta // 应用旋转到目标节点 targetNode?.eulerAngles.y = newAngle } .onEnded { _ in // 手势结束时更新当前角度,确保下次拖拽从当前位置开始 if let currentAngle = targetNode?.eulerAngles.y { currentAngleY = currentAngle } } } // 示例相机节点,可根据你的场景调整 private var cameraNode: SCNNode { let camera = SCNCamera() let node = SCNNode() node.camera = camera node.position = SCNVector3(x: 0, y: 0, z: 5) return node } }
关键要点
- 状态管理:用
@State保存currentAngleY,确保手势结束后能保留当前旋转位置,避免下次拖拽重置角度。 - 手势映射:通过
DragGesture的translation.width获取水平拖拽距离,转换为SceneKit的Y轴旋转角度(Y轴旋转对应物体水平方向转动)。 - 节点引用:初始化时提前获取目标节点,避免手势触发时重复查找节点,提升性能。
内容的提问来源于stack exchange,提问作者Mc.Lover
相关产品推荐
相关产品推荐

