SwiftUI中如何更新ObservableObject数组状态以刷新UI?
问题原因
你用@State存储ObservableObject类型的数组,@State只能检测数组本身的结构性变化(比如添加、删除元素,或替换整个数组)。但Item是引用类型,修改它内部的value属性时,数组本身并未发生变化,所以@State不会触发UI刷新。而添加新元素时,数组结构改变,@State触发刷新,此时所有Item的最新值才会被渲染出来。
解决方案
有两种常用解决方式,可根据场景选择:
方式一:将Item改为值类型(推荐简单场景)
把Item从class改成struct,值类型的属性变化会让整个Item实例发生变化,@State能检测到这种变化并即时刷新UI:
struct Item: Identifiable { var value: Int = 1 let id = UUID() } struct ContentView: View { @State var items: [Item] = [] var body: some View { List { ForEach($items) { $item in Button { item.value += 1 } label: { Text("\(item.value)") } } Button("Add Item") { items.append(Item()) } } } }
方式二:保留引用类型,用子视图单独观察Item
如果Item必须是ObservableObject(比如包含复杂业务逻辑、异步操作),可以把每个Item的按钮封装成独立子视图,用@ObservedObject观察Item实例,这样Item内部@Published属性变化时,子视图会自动刷新:
class Item: ObservableObject, Identifiable { @Published var value: Int = 1 let id = UUID() } // 封装子视图 struct ItemButtonView: View { @ObservedObject var item: Item var body: some View { Button { item.value += 1 } label: { Text("\(item.value)") } } } struct ContentView: View { @State var items: [Item] = [] var body: some View { List { ForEach(items) { item in ItemButtonView(item: item) } Button("Add Item") { items.append(Item()) } } } }
内容的提问来源于stack exchange,提问作者Berry Blue
相关产品推荐
相关产品推荐

