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

SwiftUI中数组更新后Grid视图未刷新的问题修复咨询

SwiftUI 鱼类列表不更新问题修复方案

核心问题分析

  • ObservableObject 状态标注错误:Fishies类里的数组使用了@State,但@State仅适用于View结构体内部的局部状态。ObservableObject的属性需要用@Published修饰,才能在数据变化时通知绑定的视图更新。
  • 数据实例不共享:MyPond中每次点击按钮都会创建新的Journal()实例,调用它的addFish方法完全不会影响当前界面显示的Journal视图的数据源。
  • ObservedObject 初始化逻辑错误:Journal内部直接初始化@ObservedObject var fishArray = Fishies(),会导致每次视图刷新都生成新的数据源实例,之前添加的数据会丢失。

修复步骤及完整代码

1. 修正ObservableObject的属性标注

将Fishies类中的@State替换为@Published,确保数组变化能触发视图更新:

class Fishies: ObservableObject {
    @Published var array:[Fish] = []
}

2. 共享单一数据源实例

在父视图(比如App入口或包含MyPond和Journal的容器视图)中创建Fishies的唯一实例,用@StateObject管理生命周期,再传递给子视图:

struct ContentView: View {
    // 全局共享的数据源实例
    @StateObject private var fishStore = Fishies()
    
    var body: some View {
        TabView {
            MyPond(fishStore: fishStore)
                .tabItem { Label("我的池塘", systemImage: "drop.fill") }
            Journal(fishStore: fishStore)
                .tabItem { Label("日志", systemImage: "book.fill") }
        }
    }
}

3. 修改MyPond视图直接操作共享数据源

移除局部的newFish状态,直接向共享的fishStore添加新鱼:

struct MyPond: View {
    let fishStore: Fishies
    
    var body: some View {
        VStack {
            Button(action: {
                let newFish = Fish()
                fishStore.array.append(newFish)
                // 可选:打印验证添加结果
                print("新增鱼类:\(newFish.name)")
            }) {
                Text("点击钓鱼")
                    .padding()
                    .background(Color.blue)
                    .foregroundColor(.white)
                    .cornerRadius(8)
            }
        }
        .padding()
    }
}

4. 修改Journal视图绑定共享数据源

移除冗余的addFish方法,直接使用共享的fishStore作为数据源:

struct Journal: View {
    @ObservedObject var fishStore: Fishies
    
    let columns = [
        GridItem(.flexible(), spacing: 10),
        GridItem(.flexible(), spacing: 10),
        GridItem(.flexible(), spacing: 10),
        GridItem(.flexible(), spacing: 10)
    ]
    
    var body: some View {
        ScrollView() {
            LazyVGrid(columns: columns, spacing: 10) {
                ForEach(fishStore.array){ fish in
                    FishView(fish: fish)
                }
            }
            .padding()
        }
    }
}

5. 保持Fish结构体不变

确保fishNameGenerated是已定义的字符串数组:

// 示例鱼类名称数组
let fishNameGenerated = ["金鱼", "鲤鱼", "鲈鱼", "三文鱼"]

struct Fish: Identifiable {
    var id = UUID()
    var name: String = fishNameGenerated.randomElement()!
}

修复后,MyPond和Journal共用同一个数据源实例,点击按钮添加鱼时,@Published修饰的数组会自动触发Journal视图刷新,LazyVGrid就能实时显示新添加的FishView了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 03:35:13