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

SwiftUI中基于CoreData实体初始化视图变量并填充选择器

问题解决:CoreData实体详情视图的初始化错误与数据修改实现

错误原因分析

你遇到的Variable 'self.session' used before being initialized错误,本质是SwiftUI的初始化顺序问题:

  1. @ObservedObject类型的session必须先完成初始化,才能访问它的属性
  2. @State是属性包装器,不能直接在init中给其包装值赋值,必须通过初始化底层的_state存储对象

完整修正代码

struct DetailSessionPokUIView: View {
    @Environment(\.managedObjectContext) var moc
    @ObservedObject var session: PokSession

    @State private var date: Date
    @State private var currency: String
    @State private var periode: String
    @State private var nbheure: Double

    let liste_currency = ["CAD", "EUR", "USD", "GBP"]
    let liste_periode = ["matinée", "après-midi", "soirée"]

    init(session: PokSession) {
        // 1. 先完成@ObservedObject属性的初始化
        self.session = session
        // 2. 通过State初始化器给@State属性设置初始值,添加默认值避免强制解包崩溃
        _date = State(initialValue: session.date ?? Date())
        _currency = State(initialValue: session.currency ?? "EUR")
        _periode = State(initialValue: session.periode ?? "matinée")
        _nbheure = State(initialValue: session.nbheure)
    }

    var body: some View {
        NavigationView {
            Form {
                Section {
                    DatePicker(selection: $date, displayedComponents: .date) {
                        Text("Date")
                    }
                    
                    Picker("Devise", selection: $currency) {
                        ForEach(liste_currency, id: \.self) { currency in
                            Text(currency)
                        }
                    }
                    
                    Picker("Période de jeu", selection: $periode) {
                        ForEach(liste_periode, id: \.self) { periode in
                            Text(periode)
                        }
                    }
                    
                    HStack {
                        Text("Temps de jeu (h)")
                            .multilineTextAlignment(.leading)
                        Slider(value: $nbheure, in: 0...24, step: 1)
                        Text("\(nbheure, specifier: "%.0f")")
                        Image(systemName: "clock")
                    }
                }
            }
            .navigationTitle("Détails de la session")
            .toolbar {
                // 添加保存按钮,实现修改后的数据持久化
                Button("Sauvegarder") {
                    // 将临时编辑的State值同步回CoreData实体
                    session.date = date
                    session.currency = currency
                    session.periode = periode
                    session.nbheure = nbheure
                    
                    // 保存上下文,完成数据持久化
                    do {
                        try moc.save()
                    } catch {
                        print("Erreur de sauvegarde : \(error.localizedDescription)")
                    }
                }
            }
        }
    }
}

关键修改说明

  1. 修正初始化逻辑

    • 先给self.session赋值,确保@ObservedObject完成初始化后再访问其属性
    • 使用_date = State(initialValue: ...)的方式初始化@State属性,符合SwiftUI属性包装器的初始化规则
    • 给可选属性添加默认值(如session.date ?? Date()),避免强制解包导致崩溃
  2. 添加数据保存功能

    • 在导航栏工具栏中添加保存按钮,将@State中临时编辑的值写回CoreData实体
    • 调用moc.save()持久化修改,确保数据变更保存到本地存储
  3. UI优化

    • 移除不必要的HStack包裹Picker,简化代码结构
    • 添加导航标题,提升用户体验

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 06:06:45