【问题标题】:Cannot get the @state variable in a ForEach loop working with SwiftUI无法在使用 SwiftUI 的 ForEach 循环中获取 @state 变量
【发布时间】:2021-02-17 14:19:41
【问题描述】:

我想生成一个带有 ForEach 循环的输入 TextField 列表。 textFields 显然是@State 变量。

我确实得到了错误:

通用结构 'ForEach' 要求 'Binding' 符合 '可哈希'

这是我的代码:

struct ContentView: View {
    @State private var mainPrice = ""
    @State private var mainGrade = ""
    
    var body: some View {
        
        var inputFields = [$mainPrice,$mainGrade]
        
        HStack {
            List{
                ForEach(inputFields, id: \.self)  { value in   /// here is the error

                    TextField("Enter data", text: value)

                    }
                }
        }
       
    }

所以,我将绑定变量放在一个数组中,因为我在循环中需要一个绑定类型,也许这不是怎么做的?我尝试将Hashable 添加到 inputFields var 以响应错误消息,但我怀疑整个设置是错误的。

【问题讨论】:

    标签: swiftui


    【解决方案1】:

    我实际上找到了另一种使用具有 id 的结构执行此操作的方法,因为主要问题似乎是数组不提供数据的精确标识。我们需要一个 id(参见视频 https://www.hackingwithswift.com/books/ios-swiftui/working-with-identifiable-items-in-swiftui):

    struct tableContent{
        var id: Int
        var label: String
        var data: Binding<String>
    }
    

    数组看起来像这样:

    let textFields = [
                tableContent(id: 1, data: $mainPrice),
                tableContent(id: 2, data: $mainGrade)
            ]
    

    还有 ForEach 循环

    List{
         ForEach(textFields, id: \.id)  { value in
             TextField("", text: value.data)
             }
         }
    

    【讨论】:

      【解决方案2】:
      struct ContentView: View {
          @State private var mainPrice = ["1000", "5000"]
      
          var body: some View {
              HStack {
                  List {
                      ForEach(mainPrice.indices, id: \.self) { index in
                          TextField("Enter data", text: $mainPrice[index])
                      }
                  }
              }
          }
      }
      

      【讨论】:

      • 如果格式正确,您的答案更有可能受到好评(因此被赞成)。也尝试添加一些你的代码的解释。
      • 我认为这适用于具有不同值的一个变量,但我追求的是在 ForEach 循环中有多个 @State 变量
      • 在我的代码中 mainPrice 不是一个变量!它是一个数据数组,以您的方式和您接受的答案,您将自己限制为 2 个变量,但在我的编码版本中,您可以拥有尽可能多的变量,您可以拥有 0 到数千个变量!如果您有超过 2 个变量,那么您的方式将失败,使用我的代码,您只需将新数据附加到现有变量。
      【解决方案3】:
      import SwiftUI
      
      struct ContentView: View {
          @State private var mainPrice = ""
          @State private var mainGrade = ""
          
          var body: some View {
              
              let inputFields = [BindingWrapper(binding: $mainPrice), BindingWrapper(binding: $mainGrade)]
              
              HStack {
                  List{
                      ForEach(inputFields, id: \.uuid)  { value in   /// here is the error
                          TextField("Enter data", text: value.$binding)
      
                      }
                  }
              }
          }
      }
      
      struct BindingWrapper {
          let uuid: UUID = UUID()
          @Binding var binding: String
      }
      

      【讨论】:

      • 哇,这行得通。我承认虽然我不明白 Bindingwrapper 在做什么以及为什么。
      • 研究你对 UUID 的使用我发现了这个有用的视频hackingwithswift.com/books/ios-swiftui/…。我越来越了解你做了什么
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多