【问题标题】:Custom Binding of State inside ForEachForEach 中的自定义状态绑定
【发布时间】:2021-06-24 02:45:07
【问题描述】:

我想在我的 Struct 类型的 State 变量中切换变量,但不知道如何构造一个自定义 Binding 到 State 的变量。 Xcode 抛出错误“Cannot assign to property: 'translations' is a 'let' constant”

带有自定义绑定的 ForEach(不起作用)

ForEach(data.translations, id: \.self) { translations in
    
    let binding = Binding(
        get: { translations.target},
        set: { translations.target = $0 }
    )
    
    HStack {
        Text("\(translations.language)")
        Spacer()
        Toggle(isOn: binding) {
            Text("")
        }
        .toggleStyle(CheckboxToggleStyle())
    }
    
}

结构

struct Data: Hashable {
    
    var base: String
    var target: String
    var translations: [Translations]
    
    struct Translations: Hashable {
        let language: String
        var target: Bool
        var texts: [String: Text]
    }
    
    struct Text: Hashable {
        var translation: String
        var pinned: Bool
        var order: Int
    }
    
}

国家

@State var data = Data(
    base: "",
    target: "",
    translations: [ // ADD ALL LANGUAGES. CHECK REMINDERS-APP FOR NOTE ABOUT LANGUAGES
        Data.Translations(
            language: "Danish",
            target: false,
            texts: [
                "..." : Data.Text(translation: "...", pinned: false, order: 0)
            ]
        ),
        Data.Translations(
            language: "Swedish",
            target: true,
            texts: [
                "..." : Data.Text(translation: "...", pinned: false, order: 0)
            ]
        ),
        Data.Translations(
            language: "English",
            target: true,
            texts: [
                "..." : Data.Text(translation: "...", pinned: false, order: 0)
            ]
        )
    ]
)

【问题讨论】:

    标签: swift swiftui


    【解决方案1】:

    您遇到了多个问题,例如命名和尝试更改 ForEach 的 let 项目,这里是救命稻草:



    struct DataStruct: Hashable {
        
        var base: String
        var target: String
        var translations: [TranslationsStruct]
        
    }
    
    struct TranslationsStruct: Hashable {
        
        let language: String
        var target: Bool
        var texts: [String: TextStruct]
        
    }
    
    struct TextStruct: Hashable {
        
        var translation: String
        var pinned: Bool
        var order: Int
        
    }
    

    var dataStructInitializing = DataStruct(
        base: "",
        target: "",
        translations: [
            TranslationsStruct(
                language: "Danish",
                target: false,
                texts: [
                    "..." : TextStruct(translation: "...", pinned: false, order: 0)
                ]
            ),
            TranslationsStruct(
                language: "Swedish",
                target: true,
                texts: [
                    "..." : TextStruct(translation: "...", pinned: false, order: 0)
                ]
            ),
            TranslationsStruct(
                language: "English",
                target: true,
                texts: [
                    "..." : TextStruct(translation: "...", pinned: false, order: 0)
                ]
            )
        ]
    )
    

    import SwiftUI
    
    struct ContentView: View {
        
        @State private var dataStruct: DataStruct = dataStructInitializing
        
        var body: some View {
            
            VStack {
                
                ForEach(dataStruct.translations.indices, id: \.self) { index in
                    
                    let binding = Binding(
                        get: { dataStruct.translations[index].target },
                        set: { dataStruct.translations[index].target = $0 }
                    )
    
                    Toggle(isOn: binding) { Text(dataStruct.translations[index].language) }
    
                }
                
            }
            .padding()
            
        }
    }
    

    【讨论】:

      【解决方案2】:
      struct ContentView: View {
          @State private var dataStruct: DataStruct = dataStructInitializing
          var body: some View {
              VStack {
                  ForEach($dataStruct.translations, id: \.self) { $translation in
                      Toggle(isOn: $translation.target) { Text(translation.language) }
                  }
              }
              .padding()
          }
      }
      

      另外,制作translations Identifiable 并使用他们的.id 代替.self 也是一个好主意。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-03-14
        • 2016-08-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-01
        • 1970-01-01
        相关资源
        最近更新 更多