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

Swift ML Vision:如何从UIViewController扩展更新Environment数组

解决方法

核心思路是把环境中的ScannedItems实例传递给CaptureViewController,让其扩展能直接访问并更新数组,具体步骤如下:

1. 给CaptureViewController添加ScannedItems属性

在CaptureViewController的主类定义中,添加一个可选的ScannedItems属性,确保扩展能访问到它:

class CaptureViewController: UIViewController {
    // 保留原有属性与方法
    var scannedItems: ScannedItems?
}

2. 在UIViewControllerRepresentable中传递环境对象

在你的UIViewControllerRepresentable结构里,通过@EnvironmentObject获取ScannedItems实例,创建CaptureViewController时把实例赋值给它的对应属性:

struct CaptureView: UIViewControllerRepresentable {
    @EnvironmentObject private var scannedItems: ScannedItems
    
    func makeUIViewController(context: Context) -> CaptureViewController {
        let vc = CaptureViewController()
        vc.scannedItems = scannedItems
        return vc
    }
    
    func updateUIViewController(_ uiViewController: CaptureViewController, context: Context) {
        // 按需处理视图更新逻辑
    }
}

3. 在extractDetections中更新数组

在CaptureViewController的扩展里,拿到scannedItems实例后,就可以检测新物品并更新数组。注意必须在主线程更新——因为@Published属性的修改会触发UI刷新,线程错误会导致异常:

extension CaptureViewController {
    func extractDetections(_ detections: [Detection]) {
        for detection in detections {
            let itemName = detection.label // 替换成你实际的物品标识字段
            
            DispatchQueue.main.async {
                guard let scannedItems = self.scannedItems else { return }
                // 检查物品是否已存在,不存在则添加
                if !scannedItems.list.contains(itemName) {
                    scannedItems.list.append(itemName)
                }
            }
        }
    }
}

关键注意点

  • 确保ContentView已经通过.environmentObject(ScannedItems())完成环境对象注入,否则@EnvironmentObject会引发崩溃
  • 所有对@Published属性的修改必须放在主线程,避免线程冲突和UI刷新异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 03:06:29