SwiftUI中如何接收UIViewController的回调并更新视图内容
解决方法
第一步:调整LogsViewModel属性声明
确保日志存储属性用@Published修饰,这样值变更时会自动通知绑定的视图刷新:
class LogsViewModel: ObservableObject { @Published var fullLogMessage: String = "" }
第二步:给AdsScreenView_UI传递LogsViewModel实例
在父视图TestAdsView中初始化AdsScreenView_UI时,把持有的lvm作为参数传入,方便在updateUIViewController中访问:
struct TestAdsView: View { @StateObject var lvm: LogsViewModel = LogsViewModel() // 补充你遗漏的AdsScreenViewModel声明,根据你的实际代码调整即可 @StateObject var vm: AdsScreenViewModel = AdsScreenViewModel() var body: some View { VStack{ Text(vm.adStatus.rawValue) // 直接绑定@Published属性即可,不需要额外的get计算属性 TextField("Logs", text: $lvm.fullLogMessage) Button("load Ads", action: { vm.loadAds() }) // 传入lvm参数 AdsScreenView_UI(viewModel: vm, lvm: lvm).frame(width: 0, height: 0) } } }
第三步:在updateUIViewController中更新日志值
AdsScreenView_UI新增lvm属性后,直接在回调触发时把拿到的消息赋值给lvm.fullLogMessage,TextField会自动同步更新:
struct AdsScreenView_UI: UIViewControllerRepresentable{ @ObservedObject var viewModel: AdsScreenViewModel // 新增LogsViewModel属性 @ObservedObject var lvm: LogsViewModel func makeUIViewController(context: Context) -> some AdsScreenViewController { print(#function) return AdsScreenViewController(viewModel: viewModel) } func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) { // 假设你从viewModel中获取到新的日志消息,根据你的实际属性名调整即可 let newLogContent = viewModel.newReceivedLog guard !newLogContent.isEmpty else { return } // 需要拼接历史日志就用+=,直接覆盖就用= lvm.fullLogMessage += "\n\(newLogContent)" } }
核心说明
@Published修饰的属性值变更时,会自动触发所属ObservableObject的对象变更通知,所有绑定该属性的视图都会自动刷新- 你需要确保
AdsScreenViewModel中存储回调日志的属性也用@Published修饰,这样新日志到来时才会触发updateUIViewController调用
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

