在视图中设置所有变量

Set all variables in view

问题:如何轻松更改 ForEach 语句内单独视图中的所有变量? (查看代码中的备注。)

ContentView()

@State var isShowing = false

var body: some View {
    Toggle("IsShowing", isOn: $isShowing)
          .onChange(of: isShowing) {
              if isShowing {
                 //Set all var `Toggled` in ToggleView() to `true`
              } else {
                 //Set all var `Toggled` in ToggleView() to `false`
                }    
          }
    Spacer()
    if IsShowing {
        ForEach(StaffList, id: \.self) { item in
              ToggledView()
        }
    }
}

ToggledView()

@State var Toggled = false

var body: some View {
     if Toggled {
        Text("True")
    } else {
        Text("False")
    }
}

有什么问题欢迎提问

您在问题中提供的代码存在一些问题,无法立即重现;让我举例说明:

  • 您有两个不同的变量,IsShowingisShowing:这是打字错误,还是它们应该不同? IsShowing 完全隐藏列表。我假设他们有不同的目的。
  • 最好遵循 Swift 中的约定:所有变量都以小写开头,因此避免将 IsShowingStaffList 作为变量名。
  • 无论如何,上面代码中的列表是不可见的,因为当你在正文中有多个视图时,你需要将它们嵌入到一个容器中,例如 VStack
  • onChange(of:perform:) 在闭包中接受一个参数,上面的代码无法编译 - 注意,因为 SwiftUI 在这种情况下会抛出具有误导性的错误。
  • 您想更改 ToggledView 中的所有开关:变量 toggled 可用于该目的,但我假设它具有局部作用域,因此我添加了 Toggle 在我下面的示例中。

解决方法:需要将父视图中的变量与子视图中的另一个变量绑定,然后监听子变量的变化。

父视图有一个@State变量,它需要传递给子视图中的一个@Binding变量。您用 .onChange(of:) { }.

收听变化

在下面的代码中,列表中的每个项目都有自己特定的切换,但是当您更改视图顶部的那个时,所有项目都会相应地改变。

父视图:

struct ContentView: View {
    let isShowingList = true   // This replaces the "IsShowing" variable in the question
    
    @State var isShowing = false
    
    var body: some View {
        
        // Embed content in a container, like VStack
        VStack {
            
            Toggle("Toggle all items", isOn: $isShowing)
                .padding()
            
            Spacer()
            
            if isShowingList {
                ForEach(staffList, id: \.self) { item in
                    
                    // Pass the variable from this view to the child view
                    ToggledView(globalToggle: $isShowing)
                }
            }
            
            Spacer()
        }
        .padding()
    }
}

子视图:

struct ToggledView: View {
    
    // Make state variables private
    @State private var toggled = false
    
    // This is where the magic happens: changing iShowing in the parent view
    // will change globalToggle in this view
    @Binding var globalToggle: Bool
    
    var body: some View {
        Toggle(toggled ? "True" : "False", isOn: $toggled)

        // .onChange(of:) closure receives one parameter: the variable changed
            .onChange(of: globalToggle) { value in
                toggled = value
            }
    }
}