SwiftUI中无法在视图内显示3D立方体的技术求助
问题解决:SwiftUI中显示SceneKit立方体
你的代码存在几个关键问题导致立方体无法渲染显示,以下是具体修复方案:
核心问题分析
- SwiftUI与UIKit适配错误:直接在SwiftUI的
body中返回Viewer(UIViewController子类)不符合SwiftUI的视图规则,必须通过UIViewControllerRepresentable协议完成UIKit视图控制器到SwiftUI视图的转换。 - 缺少相机节点:SceneKit场景默认没有相机组件,即使添加了立方体和灯光,没有相机也无法将3D画面渲染到屏幕上。
- SCNView布局未适配:仅设置
frame: self.view.frame无法让SCNView随父视图自动调整尺寸,需要添加自动布局约束。
修复后的完整代码
import SwiftUI import SceneKit struct ContentViewC: View { var body: some View { SceneKitCubeView() .edgesIgnoringSafeArea(.all) } } // 实现UIViewControllerRepresentable协议,适配UIKit控制器到SwiftUI struct SceneKitCubeView: UIViewControllerRepresentable { func makeUIViewController(context: Context) -> Viewer { Viewer() } func updateUIViewController(_ uiViewController: Viewer, context: Context) {} } class Viewer: UIViewController { override func viewDidLoad() { super.viewDidLoad() let myView = SCNView() myView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(myView) // 添加全屏约束,让SCNView适配父视图 NSLayoutConstraint.activate([ myView.topAnchor.constraint(equalTo: view.topAnchor), myView.leadingAnchor.constraint(equalTo: view.leadingAnchor), myView.trailingAnchor.constraint(equalTo: view.trailingAnchor), myView.bottomAnchor.constraint(equalTo: view.bottomAnchor) ]) let myScene = SCNScene() myView.scene = myScene myView.allowsCameraControl = true // 允许手势控制相机(可选,方便调试) myView.backgroundColor = .black // 创建立方体节点 let myBox = SCNBox(width: 15, height: 10, length: 12, chamferRadius: 0) let myBoxNode = SCNNode(geometry: myBox) myBoxNode.position = SCNVector3(x: 0, y: 0, z: 0) myBoxNode.rotation = SCNVector4(x: 1, y: 1, z: 0.5, w: 0.6) myScene.rootNode.addChildNode(myBoxNode) // 添加灯光 let myLight = SCNLight() myLight.type = .omni myLight.color = .yellow let myLightNode = SCNNode() myLightNode.light = myLight myLightNode.position = SCNVector3(x: -30, y: 30, z: 60) myScene.rootNode.addChildNode(myLightNode) // 添加相机(核心:没有相机无法渲染画面) let camera = SCNCamera() let cameraNode = SCNNode() cameraNode.camera = camera cameraNode.position = SCNVector3(x: 0, y: 0, z: 50) // 放置在正对立方体的位置 myScene.rootNode.addChildNode(cameraNode) } } // 预览视图 struct ContentViewC_Previews: PreviewProvider { static var previews: some View { ContentViewC() } }
关键修改说明
- UIKit适配层:通过
SceneKitCubeView结构体完成UIViewController到SwiftUI视图的转换,符合SwiftUI的视图渲染规则。 - 相机节点添加:新增相机并设置合适位置,确保能捕捉到立方体的3D画面。
- 自动布局:禁用自动转换约束并添加全屏约束,让SCNView随父视图自适应尺寸。
- 调试优化:开启
allowsCameraControl后,可通过手势旋转、缩放相机,方便查看3D物体的不同角度。
内容的提问来源于stack exchange,提问作者Edward Taylor
相关产品推荐
相关产品推荐

