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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 14:22:42