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

如何通过点击RealityKit中的实体打开SwiftUI视图?

方案一:使用NavigationLink实现导航

要在点击RealityKit实体后触发SwiftUI的NavigationLink导航,核心是通过绑定变量将AR视图中的点击事件传递到SwiftUI的视图层级中,具体修改步骤如下:

  1. 修改ARViewContainer.swift
    • 给Coordinator类添加绑定属性,用于触发导航状态变化
    • 在ARViewContainer结构体中添加@Binding变量,关联SwiftUI的状态
    • 在点击实体的回调中设置绑定变量为true,触发导航

修改后的代码:

class Coordinator: NSObject {
    weak var view: ARView?
    var shouldNavigate: Binding<Bool> // 新增绑定属性

    init(shouldNavigate: Binding<Bool>) {
        self.shouldNavigate = shouldNavigate
        super.init()
    }

    @objc func handleTap(_ recognizer: UITapGestureRecognizer) {
        guard let view = self.view else { return }
        let tapLocation = recognizer.location(in: view)
        
        if let entity = view.entity(at: tapLocation) as? ModelEntity {
            print(entity.name)
            shouldNavigate.wrappedValue = true // 触发导航状态
        }
    }
}

struct ARViewContainer: UIViewRepresentable {
    typealias UIViewType = ARView
    @Binding var shouldNavigate: Bool // 新增绑定变量

    func makeUIView(context: Context) -> ARView{
        let arView = ARView(frame: .zero, cameraMode: .ar, automaticallyConfigureSession: true)
        
        context.coordinator.view = arView
        arView.addGestureRecognizer(UITapGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.handleTap)))
        
        arView.scene.anchors.removeAll()

        let anchor = AnchorEntity()
        let plane = MeshResource.generatePlane(width: 1, height: 1)
        
        var material = UnlitMaterial()
        material.color = .init(tint: .white,
                            texture: .init(try! .load(named: "instagram")))
        
        let planeEntity = ModelEntity(mesh: plane, materials: [material])
        planeEntity.generateCollisionShapes(recursive: true)
        planeEntity.name = "Plane Entity"
        planeEntity.position.z -= 1.0
        planeEntity.setParent(anchor)
        arView.scene.addAnchor(anchor)
        
        return arView
    }
    
    func updateUIView(_ uiView: ARView, context: Context){}
    
    func makeCoordinator() -> Coordinator {
        Coordinator(shouldNavigate: $shouldNavigate) // 初始化协调器时传入绑定
    }
}
  1. 修改ContentView.swift
    • 添加@State变量管理导航状态
    • 加入绑定到该状态的NavigationLink(用EmptyView作为占位,避免影响AR视图显示)

修改后的代码:

struct ContentView: View {
    @State private var shouldNavigate = false

    var body: some View {
        NavigationView{
            ZStack {
                ARViewContainer(shouldNavigate: $shouldNavigate)
                    .ignoresSafeArea(.all)
                
                // 绑定状态的NavigationLink,占位视图不影响界面
                NavigationLink(
                    destination: TestView(),
                    isActive: $shouldNavigate,
                    label: { EmptyView() }
                )
            }
        }
    }
}

方案二:使用fullScreenCover实现全屏跳转

如果NavigationLink不符合需求,可改用fullScreenCover,只需修改ContentView.swift的代码即可(ARViewContainer的修改和方案一一致):

修改后的ContentView:

struct ContentView: View {
    @State private var shouldNavigate = false

    var body: some View {
        ZStack {
            ARViewContainer(shouldNavigate: $shouldNavigate)
                .ignoresSafeArea(.all)
        }
        .fullScreenCover(isPresented: $shouldNavigate) {
            TestView()
        }
    }
}

核心原理说明

  • 通过@Binding在UIKit(ARView)和SwiftUI视图之间建立状态传递通道,让AR视图中的点击事件能触发SwiftUI的导航逻辑
  • 两种方案都无需修改TestView的代码,保持原有结构即可

内容的提问来源于stack exchange,提问作者Milly Alfaro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 20:50:29