Как изменить ввод пользователя внутри цикла формы SwiftUI

Я разрабатываю простое приложение SwiftUI в Xcode 11. Я хочу иметь форму, которая проходит через несколько строк ввода пользователя и отображает форму с помощью кнопки. Когда пользователь нажимает кнопку, он изменяет входное значение - в частности, увеличивает или уменьшает его.

Однако при передаче массива ссылок, таких как UserInput().foo, где UserInput является опубликованным наблюдаемым объектом, я не могу изменить значение внутри 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)
    }
}

person howardgrigg    schedule 04.07.2020    source источник
comment
Я не могу уловить смысла этого снимка, он вообще не работает с var input. Не могли бы вы рассказать подробнее?   -  person Asperi    schedule 04.07.2020


Ответы (1)


Как я понял, при добавлении значения в userinputs значения ForEach не меняются. Что ж, если это так, во-первых, вы можете попробовать создать структуру и в ней объявить foo и bar, а затем просто объявить переменную типа struct. Это будет выглядеть так:

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)
    }
}

Разве не было бы проще и изящнее?

person S_dnomseD    schedule 08.12.2020