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

SwiftUI中swipeActions唤起Popover改值后视图不更新问题

问题原因与解决方案

问题根源

ContentView中的List仅监听@State数组countries的整体变动(比如元素增删),但Country对象内部的@Published属性(population)变化时,数组本身并未改变,因此SwiftUI不会自动刷新对应的列表行。

具体修改步骤

1. 让列表行监听Country对象的内部变化

在List的闭包中,将country声明为@ObservedObject,这样当Country的@Published属性更新时,该行UI会自动刷新:

List(countries, id: \.id) { @ObservedObject country in
    HStack {
        Spacer()
        Text(country.code)
        Spacer()
        Text("\(country.population)")
        Spacer()
    }
    .font(.title)
    .swipeActions(content: {
        Button { 
            selectedCountry = country
            showPopover = true 
        } label: { Text("Update") }
    })
}

2. 调整PopoverView的对象引用方式

由于Country是ObservableObject,无需通过@Binding传递,直接用@ObservedObject接收对象引用即可,确保修改能同步通知到所有观察者:

struct PopoverView: View {
    @Environment(\.presentationMode) var presentationMode
    @ObservedObject var country: Country // 替换原@Binding
    @State var value = "???"

    var body: some View {
        HStack {
            Spacer()
            Text(country.code)
            TextField(country.code, text: $value)
            Button {
                if let intValue = Int(value) { 
                    country.population = intValue 
                }
                print("New population: \(country.population)")
                presentationMode.wrappedValue.dismiss()
            } label: { Text("DONE")}
            Spacer()
        }.onAppear {
            value = String(country.population)
        }
    }
}

3. 更新ContentView中Popover的调用

去掉绑定符号,直接传递选中的Country对象:

.popover(isPresented: $showPopover) {
    PopoverView(country: selectedCountry)
}

修改后效果

当在Popover中修改人口数值并点击"DONE"后,Country的population属性通过@Published发出通知,对应的列表行因@ObservedObject监听而自动刷新,显示最新数值。

内容的提问来源于stack exchange,提问作者Robert

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 18:08:45