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

SwiftUI技术问题:如何在ForEach循环中设置Toggle的isOn参数

嗨,我来帮你搞定这个问题!

你遇到的错误是因为SwiftUI的Toggle组件需要的是Binding<Bool>类型的参数,而你直接传入了结构体里的普通Bool值——这俩不是一回事儿。普通的Bool只是个静态值,没法让Toggle在用户点击时更新源数据并同步视图,而Binding相当于一个“双向连接”,能把Toggle的状态变化同步回你的数据模型里。

下面是具体的解决步骤,分两种常见场景:

方案一:绑定整个Sandwich对象

首先得确保你的数据结构体是可变的(属性用var而不是let),比如你的Sandwich和Ingredient大概长这样:

struct Sandwich: Identifiable {
    let id = UUID()
    var ingredients: [Ingredient]
    // 其他属性比如名字、价格之类的...
}

struct Ingredient: Identifiable {
    let id = UUID()
    let name: String
    var isToggleOn: Bool // 这里必须是var,才能被修改
}

然后修改你的IngredientView,把原本的var sandwich: Sandwich改成@Binding var sandwich: Sandwich,这样子视图就能读写父视图的状态了。同时,遍历的时候要用绑定版本的ForEach:

import SwiftUI

struct IngredientView: View {
    @Binding var sandwich: Sandwich // 改成@Binding,建立双向绑定
    
    var body: some View {
        // 用$sandwich.ingredients来遍历,每个元素都是Binding<Ingredient>
        ForEach($sandwich.ingredients) { $ingredient in
            HStack {
                Text(ingredient.name)
                // 直接用$ingredient.isToggleOn,这就是Binding<Bool>类型
                Toggle("", isOn: $ingredient.isToggleOn)
                    .toggleStyle(CheckboxToggleStyle(style: .square))
                    .foregroundColor(.blue)
            }
        }
    }
}

最后在父视图里,你需要用@State来持有Sandwich实例,然后传递绑定给IngredientView:

struct ParentView: View {
    // 用@State存储状态,这样变化时会自动刷新视图
    @State private var mySandwich = Sandwich(ingredients: [
        Ingredient(name: "生菜", isToggleOn: true),
        Ingredient(name: "番茄", isToggleOn: true),
        Ingredient(name: "芝士", isToggleOn: true)
    ])
    
    var body: some View {
        // 传递$mySandwich,把绑定传给子视图
        IngredientView(sandwich: $mySandwich)
    }
}

方案二:只绑定Ingredients数组

如果不想把整个Sandwich传给子视图,也可以只传递Ingredients的绑定,这样更灵活:

struct IngredientView: View {
    @Binding var ingredients: [Ingredient] // 直接绑定数组
    
    var body: some View {
        ForEach($ingredients) { $ingredient in
            HStack {
                Text(ingredient.name)
                Toggle("", isOn: $ingredient.isToggleOn)
                    .toggleStyle(CheckboxToggleStyle(style: .square))
                    .foregroundColor(.blue)
            }
        }
    }
}

// 父视图调用时这样传
IngredientView(ingredients: $mySandwich.ingredients)

为什么这样能解决问题?

  • @Binding让子视图和父视图的状态共享,Toggle的点击会直接修改父视图里的Ingredient数据。
  • ForEach($sandwich.ingredients)会创建一个绑定到每个数组元素的遍历,这样$ingredient.isToggleOn正好是Toggle需要的Binding<Bool>类型,完美匹配参数要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 15:42:28