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

SwiftUI中无法在视图内显示3D立方体的技术求助

问题解决:SwiftUI中显示SceneKit立方体

你的代码存在几个关键问题导致立方体无法渲染显示,以下是具体修复方案:

核心问题分析

  1. SwiftUI与UIKit适配错误:直接在SwiftUI的body中返回Viewer(UIViewController子类)不符合SwiftUI的视图规则,必须通过UIViewControllerRepresentable协议完成UIKit视图控制器到SwiftUI视图的转换。
  2. 缺少相机节点:SceneKit场景默认没有相机组件,即使添加了立方体和灯光,没有相机也无法将3D画面渲染到屏幕上。
  3. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 10:00:52