Создание подкласса TextField и передача ему состояния в SwiftUI - PullRequest
1 голос
/ 04 августа 2020

Я пытаюсь создать подкласс TextField, чтобы очистить код. В настоящее время у меня есть одна «строка» текстового поля в моем Form, но в конечном итоге я хотел бы найти способ сделать это масштабируемым (и иметь намного больше HStack s).

Form {
    Section {
        HStack {
            Text("Balance")
                .foregroundColor(Color.white)
            TextField("", text: $balance, onEditingChanged: { (changing) in
                print("Changing: \(changing)")
            }, onCommit: {
                print("Committed!")
            })
            .multilineTextAlignment(.trailing)
            .foregroundColor(Color.white)
            .keyboardType(.numbersAndPunctuation)
            .onReceive(Just(balance)) { newValue in
                    let filtered = newValue.filter { "0123456789".contains($0) }
                    if filtered != newValue {
                        self.balance = filtered
                }
            }
            .placeHolder(
                Text("$0.00")
                    .frame(maxWidth: .infinity, alignment: .trailing)
                    .multilineTextAlignment(.trailing)
                    .foregroundColor(Color(#colorLiteral(red: 0.3492315412, green: 0.3486715555, blue: 0.3704651594, alpha: 1))),
                show: balance.isEmpty)
        }
    }
    .listRowBackground(Color(#colorLiteral(red: 0.1923851669, green: 0.1917944849, blue: 0.2135801911, alpha: 1)))
}

I не хочу повторять объявление HStack 4 раза (количество строк). Итак, мне нужно создать подкласс. Однако мне нужно найти способ передать состояние (знак доллара) в подкласс. Как? Кроме того, есть ли способ иметь массив состояний, чтобы я мог использовать ForEach? Пример:

var imaginaryArrayWithStates = [$textFieldValue1, $textFieldValue2] // you can't do this, but I would like to iterate states somehow...

// ...so that I can use a ForEach
ForEach(imaginaryArrayWithStates) { state
    MyCustomTextField() // how do I pass the state to this subclass? 
}

1 Ответ

1 голос
/ 04 августа 2020

Вы можете использовать @Binding:

struct CustomTextField: View {
    @Binding var value: String

    var body: some View {
        HStack {
            Text("Balance") // can be extracted as a variable
            TextField("", text: $value, onEditingChanged: { changing in
                print("Changing: \(changing)")
            }, onCommit: {
                print("Committed!")
            })
                .multilineTextAlignment(.trailing)
                .keyboardType(.numbersAndPunctuation)
                .onReceive(Just(value)) { newValue in
                    let filtered = newValue.filter { "0123456789".contains($0) }
                    if filtered != newValue {
                        self.value = filtered
                    }
                }
        }
    }
}
struct ContentView: View {
    @State var values = ["312", "222", ""]

    var body: some View {
        Form {
            Section {
                ForEach(values.indices, id: \.self) { index in
                    CustomTextField(value: self.$values[index])
                }
            }
        }
    }
}
...