SwiftUI中如何正确显示并更新@Published值?
问题解决:SwiftUI中Text同步展示ObservableObject的@Published变量
问题根源
你之前的代码有两个核心问题:
- 直接使用全局的
scratchpad实例时,ScratchpadDisplay视图不会自动订阅它的@Published属性变化,所以即使contents修改了,视图也不会刷新。 - 加上
$后,scratchpad.$contents返回的是Published<String>.Publisher类型,而Text的初始化器需要的是符合StringProtocol的字符串,所以会报错。
正确实现方式
要让Text同步更新,你需要让视图通过@StateObject、@ObservedObject或@EnvironmentObject来持有ObservableObject实例,这些属性包装器会自动帮视图订阅@Published属性的变化,触发视图刷新。
情况1:视图自身持有实例(iOS 14+ 推荐)
用@StateObject来管理Scratchpad实例,它会和视图生命周期绑定,自动监听变化:
class Scratchpad: ObservableObject { @Published var contents = "SCRATCHPAD" } struct ScratchpadDisplay: View { @StateObject private var scratchpad = Scratchpad() var body: some View { Text(scratchpad.contents) // 测试用:点击文本修改内容 .onTapGesture { scratchpad.contents = "已更新内容" } } }
情况2:多视图共享同一个实例
如果需要在多个视图中修改和展示contents,可以用@EnvironmentObject来共享实例:
- 在App入口注入实例:
@main struct YourApp: App { @StateObject private var scratchpad = Scratchpad() var body: some Scene { WindowGroup { ContentView() .environmentObject(scratchpad) } } }
- 展示视图(ScratchpadDisplay):
struct ScratchpadDisplay: View { @EnvironmentObject private var scratchpad: Scratchpad var body: some View { Text(scratchpad.contents) .padding() } }
- 修改视图(带输入框的编辑视图):
struct EditScratchpadView: View { @EnvironmentObject private var scratchpad: Scratchpad var body: some View { TextField("输入内容", text: $scratchpad.contents) .padding() .border(.gray) .padding() } }
- 组合视图:
struct ContentView: View { var body: some View { VStack(spacing: 20) { ScratchpadDisplay() EditScratchpadView() } } }
这样,在EditScratchpadView中修改输入框内容时,ScratchpadDisplay里的Text会自动同步更新。
内容的提问来源于stack exchange,提问作者BryanL
相关产品推荐
相关产品推荐

