0

我正在 Xcode 11 中开发一个简单的 SwiftUI 应用程序。我想要一个表单,它可以遍历多个用户输入字符串并显示一个带有按钮的表单。当用户按下按钮时,它会修改输入值——特别是增加或减少它。

但是,当传递一个引用数组时,比如UserInput().fooUserInput 是一个已发布的可观察对象,我无法修改 ForEach 内的值,因为 ForEach 传递了一个与原始引用相反的副本(至少这是我的基本理解)。然后我该如何尝试实现它?我读到过inout,每个人都说要避免它,但这肯定是一个相对普遍的问题。

我做了一个简单的例子来说明我正在尝试做的事情,但我无法完全解决:

import SwiftUI

class UserInput: ObservableObject {
    @Published var foo: String = ""
    @Published var bar: String = ""
}
struct ContentView: View {
    
    @ObservedObject var input = UserInput()
    
    var body: some View {
        LoopInputs()
    }
    func LoopInputs() -> AnyView?{
        
        var userinputs = [
            [UserInput().foo, "Foo"],
            [UserInput().bar, "Bar"]
        ]
        
        var inputs: some View{
            VStack(){
                ForEach(userinputs, id: \.self){userinput in
                    Text("\(userinput[1]): \(String(userinput[0]))")
                    Button(action: {
                        increment(input: String(userinput[0]))
                    }){
                        Text("Increase")
                    }
                }
            }
        }
        
        return AnyView(inputs)
    }
    func increment(input: String){
        var lead = Int(input) ?? 0
        lead += 1
        //    input = String(lead)
    }
}
4

1 回答 1

0

据我了解,在向用户输入添加值时, ForEach 值不会改变。好吧,如果是这样的话,首先,您可以尝试创建一个结构,并在其中声明 foo 和 bar,然后只需声明该结构类型的变量。它看起来像这样:

struct Input: Identifiable {
    var id = UUID()
    var foo: String
    var bar: String
}
class UserInput: ObservableObject {
    @Published var inputs: [Input] = [Input]()
}
//ContentView
struct ContentView: View {
    @ObservedObject var input = UserInput()
    var body: some View {
        LoopInputs()
    }
    func LoopInputs() -> AnyView? {
        var inputs: some View {
            VStack {
                ForEach(input.inputs) { userinput in
                    Text("\(userinput.bar): \(String(userinput.foo))")
                    Button(action: {
                        increment(input: String(userinput.foo))
                    }) {
                        Text("Increase")
                    }
                }
            }
        }
        return AnyView(inputs)
    }
    func increment(input: String) {
        var lead = Int(input) ?? 0
        lead += 1
    //    input = String(lead)
    }
}

不是更简单更优雅吗?

于 2020-12-08T18:33:39.133 回答