点击按钮添加行(嵌套数组):如何为指定Card添加Expense
解决单个Card内添加Expense的问题
你的问题核心在于全局的expense数组——所有Card的费用列表都绑定了这个全局数组,所以点击任何一个Card的"Add expense"按钮,都会往同一个数组里添加数据,导致所有Card都显示新增的费用。
以下是具体修改方案:
- 移除全局的
expense数组,每个Card结构体本身就自带expenses属性,用它来存储对应Card的费用数据 - 修改
addExpenses方法,让它接收当前Card的expenses数组引用,只往这个Card的数组里加数据 - 遍历费用列表时,绑定当前Card自己的
expenses数组,而非全局数组 - 修正代码里的大小写错误:
b.expensetype改为b.expenseType(和结构体属性名保持一致) - 初始化新Card时,传入空的
expenses数组
修改后的完整代码:
struct Card: Identifiable { var id = UUID() var title: String var expenses: [Expense] } struct Expense: Identifiable { var id = UUID() var expenseType: String var amount: Double = 0.0 } struct ContentView: View { @State private var cards = [Card]() var body: some View { NavigationStack { Form { List { Button("Add card") { addCard() } ForEach($cards) { $card in Section { TextField("Title", text: $card.title) Button("Add expense") { addExpenses(to: &card.expenses) } ForEach($card.expenses) { $expense in TextField("my expense", text: $expense.expenseType) TextField("amount", value: $expense.amount, format: .number) } } } } } } } func addCard() { cards.append(Card(title: "", expenses: [])) } func addExpenses(to expenses: inout [Expense]) { expenses.append(Expense(expenseType: "", amount: 0.0)) } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
关键修改说明:
- 通过
ForEach($cards) { $card }拿到每个Card的绑定引用,能直接修改对应Card的属性 addExpenses(to: &card.expenses)用inout参数直接操作当前Card的expenses数组,确保新增费用只属于这个Card- 费用列表遍历
$card.expenses,每个Card只展示自己的费用数据
内容的提问来源于stack exchange,提问作者Mark McKeon
相关产品推荐
相关产品推荐

