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

SwiftData遍历数据模型并向Sheet视图传值的实现方法

解决方案:将选中的SwiftData模型数据传递到Sheet视图

核心问题分析

你当前用isPresented绑定布尔值控制Sheet显示,这种方式无法直接传递选中的LedgerAccounts对象。SwiftUI提供了更适合传参的sheet(item:)API,也可以通过状态变量存储选中对象配合布尔值实现需求。


方法1:使用sheet(item:)(推荐)

这种方式直接绑定可选的模型对象,对象非空时自动弹出Sheet,关闭时自动清空对象,是SwiftUI官方推荐的传参方式。

步骤1:修改状态变量

替换原来的布尔值状态,改用可选的模型对象存储选中项:

@Environment(\.modelContext) private var modelContext
@Query private var accounts: [LedgerAccounts]
// 用可选对象存储选中的账户,替代原来的sheetEditAccount布尔值
@State private var selectedAccount: LedgerAccounts?

步骤2:修改编辑按钮的点击逻辑

点击编辑按钮时,将当前遍历的account赋值给selectedAccount:

// Edit Account
Button(action: {
    selectedAccount = account // 记录当前选中的账户
}, label: {
    Image(systemName: "gearshape.arrow.triangle.2.circlepath")
})
.tint(Color.blue)

步骤3:修改Sheet的调用方式

用sheet(item:)绑定selectedAccount,并将选中的对象传递给EditAccountView:

.sheet(item: $selectedAccount) { _ in
    print("Sheet Dismissed")
} content: { selectedAccount in
    EditAccountView(account: selectedAccount)
        .presentationDetents([.medium])
}

步骤4:调整EditAccountView接收参数

让子视图接收传入的账户对象,直接使用其数据:

struct EditAccountView: View {
    let account: LedgerAccounts
    // 如果需要修改数据,可添加modelContext环境变量
    // @Environment(\.modelContext) private var modelContext
    
    var body: some View {
        VStack(spacing: 20) {
            Text("编辑账户:\(account.nameOfAccount)")
                .font(.title)
            
            // 示例:绑定账户名称进行编辑(SwiftData模型属性默认支持双向绑定)
            TextField("账户名称", text: $account.nameOfAccount)
                .textFieldStyle(.roundedBorder)
            
            Text("当前余额:\(account.amountOfAccount, format: .currency(code: Locale.current.currency?.identifier ?? "USD"))")
        }
        .padding()
    }
}

注意:SwiftData的@Model模型会自动遵循Identifiable协议,这是sheet(item:)能正常工作的前提,无需额外手动实现。


方法2:布尔值+状态变量(兼容旧习惯)

如果你更习惯用布尔值控制Sheet显示,可以配合状态变量存储选中对象:

步骤1:添加状态变量

@Environment(\.modelContext) private var modelContext
@Query private var accounts: [LedgerAccounts]
@State var sheetEditAccount: Bool = false
@State private var selectedAccount: LedgerAccounts? // 新增:存储选中的账户

步骤2:修改编辑按钮逻辑

Button(action: {
    selectedAccount = account
    sheetEditAccount = true // 弹出Sheet
}, label: {
    Image(systemName: "gearshape.arrow.triangle.2.circlepath")
})
.tint(Color.blue)

步骤3:修改Sheet调用

.sheet(isPresented: $sheetEditAccount) {
    print("Sheet Dismissed")
    selectedAccount = nil // 关闭Sheet时清空选中对象
} content: {
    // 安全解包后传递给子视图
    if let account = selectedAccount {
        EditAccountView(account: account)
            .presentationDetents([.medium])
    }
}

EditAccountView的写法和方法1一致。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 19:37:24