如何扩展iOS的ARSessionDelegate并将代理结果回传至注册类?
如何将ARSession代理方法的结果传递给注册类
下面是几种实用的实现方式,根据你的场景选择即可:
方法一:使用闭包(最简洁的轻量方案)
在自定义代理类中定义闭包属性,当代理方法触发时调用闭包传递结果:
// 自定义ARSession代理类 class ARKitSessionDelegate: NSObject, ARSessionDelegate { // 定义接收ARFrame的闭包 var onFrameUpdated: ((ARFrame) -> Void)? func session(_ session: ARSession, didUpdate frame: ARFrame) { // 调用闭包,把frame传递出去 onFrameUpdated?(frame) } } // 在注册代理的类中使用 private var arKitSessionDelegate = ARKitSessionDelegate() arKitView.session.delegate = arKitSessionDelegate // 设置闭包接收结果 arKitSessionDelegate.onFrameUpdated = { frame in // 在这里处理frame数据,比如更新UI、计算空间位置等 print("收到更新的ARFrame: \(frame.camera.transform)") }
方法二:自定义代理协议(适合多类型结果传递)
如果需要传递多种事件(比如错误、追踪状态变化),自定义协议会让逻辑更清晰:
// 自定义输出代理协议 protocol ARKitSessionOutputDelegate: AnyObject { func arSessionDidUpdateFrame(_ frame: ARFrame) func arSessionDidFail(with error: Error) } // 自定义ARSession代理类 class ARKitSessionDelegate: NSObject, ARSessionDelegate { // 弱引用避免循环引用 weak var outputDelegate: ARKitSessionOutputDelegate? func session(_ session: ARSession, didUpdate frame: ARFrame) { outputDelegate?.arSessionDidUpdateFrame(frame) } func session(_ session: ARSession, didFailWithError error: Error) { outputDelegate?.arSessionDidFail(with: error) } } // 注册代理的类遵守自定义协议 class ARContainerViewController: UIViewController, ARKitSessionOutputDelegate { private var arKitSessionDelegate = ARKitSessionDelegate() override func viewDidLoad() { super.viewDidLoad() arKitView.session.delegate = arKitSessionDelegate // 设置自定义输出代理 arKitSessionDelegate.outputDelegate = self } // 实现协议方法接收结果 func arSessionDidUpdateFrame(_ frame: ARFrame) { // 处理ARFrame数据 } func arSessionDidFail(with error: Error) { // 处理错误逻辑 } }
方法三:使用通知中心(适合多类接收场景)
如果需要多个类同时接收ARSession的结果,可以用通知中心广播数据,但注意避免滥用导致代码耦合:
// 自定义ARSession代理类 class ARKitSessionDelegate: NSObject, ARSessionDelegate { func session(_ session: ARSession, didUpdate frame: ARFrame) { // 发送通知,携带frame数据 NotificationCenter.default.post( name: NSNotification.Name(rawValue: "ARFrameUpdatedNotification"), object: frame ) } } // 在注册代理的类中监听通知 class ARContainerViewController: UIViewController { private var arKitSessionDelegate = ARKitSessionDelegate() override func viewDidLoad() { super.viewDidLoad() arKitView.session.delegate = arKitSessionDelegate // 添加通知监听 NotificationCenter.default.addObserver( self, selector: #selector(handleFrameUpdate(_:)), name: NSNotification.Name(rawValue: "ARFrameUpdatedNotification"), object: nil ) } @objc private func handleFrameUpdate(_ notification: Notification) { guard let frame = notification.object as? ARFrame else { return } // 处理frame数据 } deinit { // 移除通知监听,避免内存泄漏 NotificationCenter.default.removeObserver(self) } }
内容的提问来源于stack exchange,提问作者narner
相关产品推荐
相关产品推荐

