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

Swift中如何将ARView传递给Coordinator?

解决ARView传递给Coordinator的问题

你遇到的核心问题是**makeCoordinator()会在makeUIView()之前执行**,所以没法在初始化Coordinator的时候直接把刚创建的ARView传进去。不过我们可以通过给Coordinator加一个可选属性,在创建完ARView之后再赋值的方式解决,同时还要注意避免循环引用(因为ARView持有手势识别器,手势识别器持有Coordinator,如果Coordinator强持有ARView就会形成循环引用)。

下面是修改后的完整代码:

struct ARViewContainer: UIViewRepresentable{
    @Binding var focusObject: Entity?
    @Binding var focusName: String?
    
    func makeUIView(context: Context) -> ARView {
        let myARView = ARView(frame: .zero)
        // ...你的ARView配置代码...
        
        let tapGesture = UITapGestureRecognizer(target: context.coordinator, action: #selector(context.coordinator.handleTap(_:)))
        myARView.addGestureRecognizer(tapGesture)
        
        // 关键一步:把创建好的ARView赋值给Coordinator的view属性
        context.coordinator.view = myARView
        
        return myARView
    }
    
    func makeCoordinator() -> Coordinator {
        // 初始化Coordinator时只传Binding,不用传ARView
        Coordinator(self.$focusObject, self.$focusName)
    }
    
    class Coordinator: NSObject {
        // 使用weak修饰ARView,避免循环引用
        weak var view: ARView?
        private var object: Binding<Entity?>
        private var objectname: Binding<String?>
        
        // 初始化方法只接收Binding参数
        init(_ obj: Binding<Entity?>, _ objname: Binding<String?>) {
            self.objectname = objname
            self.object = obj
            super.init()
        }
        
        @objc func handleTap(_ sender: UIGestureRecognizer? = nil) {
            // 先确保view存在
            guard let view = self.view else { return }
            guard let touchInView = sender?.location(in: view) else { return }
            guard let hitEntity = view.entity(at: touchInView) else {return}
            
            // 这里就可以正常使用view和Binding了
            object.wrappedValue = hitEntity
            objectname.wrappedValue = hitEntity.name
        }
    }
}

关键修改点说明:

  • 把Coordinator里的private let view: ARView改成weak var view: ARView?:用weak避免循环引用,因为ARView → 手势识别器 → Coordinator,如果Coordinator强引用ARView,三者会互相持有导致内存泄漏。
  • 修改Coordinator的初始化方法,去掉ARView参数,只接收Binding:因为初始化时还没有ARView实例。
  • 在makeUIView()里创建完ARView后,赋值给context.coordinator.view:这时候ARView已经存在,就能把它传递给Coordinator了。
  • 在handleTap里先判断view不为nil:因为view是可选类型,要确保它存在再使用。

这样就能在handleTap里同时访问ARView和你的Binding属性了,而且也符合SwiftUI的生命周期要求,不会因为视图重建出问题。

内容的提问来源于stack exchange,提问作者Sergei Masliukov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 20:02:36