You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 23:55:12