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
相关产品推荐
相关产品推荐

