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

SwiftUI中如何修改@EnvironmentObject列表中的数据?

问题分析与解决方案

你的核心问题是编辑数据后MainView未同步更新,主要由两个原因导致:编辑状态未正确初始化、值类型数组的更新未触发@Published通知,以下是具体解决步骤:


1. 初始化编辑页面的状态变量

当前EditFishingView中的fishingName和fishingType初始值为空,打开编辑页面时不会显示原有数据,导致保存时可能未真正修改内容。需要在页面出现时将状态变量初始化为当前fishing的属性值:

struct EditFishingView: View {
    @EnvironmentObject var fishingData: FishingData
    @Binding var fishing: Fishing
    @Binding var showEditView: Bool
    @State private var fishingName: String = ""
    @State private var fishingType: FishingType = .fishingLog
    
    var body: some View {
            ScrollView(.vertical, showsIndicators: false) {
                VStack(alignment: .leading, spacing: 10) {
                    EF_HeaderView(fishing: $fishing, fishingName: $fishingName, fishingType: $fishingType)
                }
                .shadow(color: .gray, radius: 4, x: 0, y: 2)
                .padding(10)
            }
            .background(Color(red: 242/255, green: 242/255, blue: 247/255))
            .navigationBarTitleDisplayMode(.inline)
            .navigationTitle(fishing.name)
            // 添加onAppear初始化状态
            .onAppear {
                fishingName = fishing.name
                fishingType = fishing.type
            }
            .toolbar {
                // 原有toolbar代码不变
            }
    }
}

2. 确保数组更新触发视图刷新

由于Fishing是值类型,仅修改Binding对象的属性不会触发@Published var mockFishings的更新通知(数组整体值未改变)。需要直接修改并替换数组中的元素,强制触发@Published的更新:

// 修改EditFishingView中"Готово"按钮的逻辑
Button("Готово") {
    guard let index = fishingData.mockFishings.firstIndex(where: { $0.id == fishing.id }) else {
        showEditView = false
        return
    }
    // 创建修改后的副本
    var updatedFishing = fishingData.mockFishings[index]
    updatedFishing.name = fishingName
    updatedFishing.type = fishingType
    // 替换数组元素,触发@Published更新
    fishingData.mockFishings[index] = updatedFishing
    
    print("fishingData ID\(index)")
    print(updatedFishing.name)
    print(fishingData.mockFishings[index].name)
    print("Fishing ID\(updatedFishing.id)")
    
    showEditView = false
}

3. 简化导航链接的写法(可选优化)

当前MainView中用透明NavigationLink的写法容易引发状态异常,建议改为常规写法:

// MainView中的List部分修改为:
List {
    ForEach($fishingData.mockFishings) { $fishing in
        NavigationLink(destination: DetailFishingView(fishing: $fishing)) {
            FishingItem(fishingData: fishing)
        }
        .listRowBackground(RoundedRectangle(cornerRadius: 10)
            .fill(Color.white)
            .padding(2))
    }
    .onDelete(perform: { indexSet in
        fishingData.delete(indexSet)
    })
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 14:35:55