SwiftUI中SceneKit场景无法自动刷新的解决方法咨询
解决SceneKit场景在SwiftUI中无法自动刷新的问题
你的问题核心是节点的显示逻辑仅在视图初始化时执行了一次,后续orderModel的状态变化无法触发场景更新。以下是修复方案和完整代码:
修复后的完整代码
import SwiftUI import SceneKit import CoreData // 确保OrderViewModel的属性可被SwiftUI监听 class OrderViewModel: ObservableObject { @Published var upJow: Bool = false @Published var lowJow: Bool = false } struct ScullView: UIViewRepresentable { @Binding var scene: SCNScene? @EnvironmentObject var orderModel: OrderViewModel func makeUIView(context: Context) -> SCNView { let view = SCNView() view.allowsCameraControl = false view.autoenablesDefaultLighting = true view.antialiasingMode = .multisampling4X view.backgroundColor = .clear view.scene = scene // 初始化时设置一次节点状态 updateNodeVisibility(in: view) return view } func updateUIView(_ uiView: SCNView, context: Context) { // 状态变化时自动触发,更新节点显示 updateNodeVisibility(in: uiView) } // 抽离节点状态更新逻辑,复用代码 private func updateNodeVisibility(in view: SCNView) { guard let scene = view.scene else { return } let lowJow = scene.rootNode.childNode(withName: "Mandibola", recursively: true) let upJow = scene.rootNode.childNode(withName: "up", recursively: true) lowJow?.isHidden = !orderModel.lowJow upJow?.isHidden = !orderModel.upJow } func makeCoordinator() -> Coordinator { Coordinator() } class Coordinator: NSObject {} } struct FormulaView: View { @State var scene: SCNScene? = .init(named: "scull.scn") @EnvironmentObject var orderModel: OrderViewModel @Namespace var animation var body: some View { VStack { ScullView(scene: $scene) .frame(width: 500, height: 500, alignment: .top) .padding(.top, -50) .padding(.bottom, -15) .zIndex(-450) Spacer() VStack { Toggle("UJ", isOn: $orderModel.upJow) .padding(.vertical, 10) Toggle("LJ", isOn: $orderModel.lowJow) .padding(.vertical, 10) } } .padding() } }
关键修改说明
- 复用节点更新逻辑:把原来仅在
makeUIView中执行的节点显示判断,抽离为updateNodeVisibility方法,既用于初始化,也用于状态更新。 - 利用
updateUIView触发刷新:SwiftUI的UIViewRepresentable中,updateUIView会在绑定状态(如orderModel的@Published属性)变化时自动调用,这里我们在该方法中更新节点的isHidden状态。 - 移除冗余视图实例:删除了
ScullView中多余的let view = SCNView(),避免和makeUIView创建的视图混淆。 - 确保状态可监听:给
orderModel的upJow和lowJow添加@Published包装器,让SwiftUI能检测到属性变化,进而触发ScullView的更新。
修改完成后,切换Toggle开关时,SceneKit场景中的对应节点会立即显示或隐藏,无需重新打开视图。
内容的提问来源于stack exchange,提问作者Adrian Shykunets
相关产品推荐
相关产品推荐

