Я пытаюсь понять, как связать @Binding
, переданный в пользовательское представление, с @Published
из модели этого представления. По сути, я пытаюсь создать многоразовое целое только TextField. Я использую приведенный ниже код, который работает для установки целочисленного значения в текстовое поле, но я не могу понять, как обновить привязку при изменении текста.
private class IntegerTextFieldValue: ObservableObject {
@Published var value = "" {
didSet {
let numbersOnly = value.filter { $0.isNumber }
if value != numbersOnly {
value = numbersOnly
}
}
}
}
struct IntegerTextField: View {
@Binding var value: Int?
@StateObject private var fieldValue = IntegerTextFieldValue()
var placeholder = ""
var body: some View {
TextField(placeholder, text: $fieldValue.value)
.keyboardType(.numberPad)
.onAppear {
if let value = value {
fieldValue.value = "\(value)"
}
}
}
}
Если я правильно тебя понял
.onChange (of: fieldValue.value) { vl in
value = vl
}
этот модификатор обновляет привязку value
к $fieldValue.value
Вот модифицированный код для демонстрации возможного подхода (проверено с помощью Xcode 12.1/iOS 14.1):
private class IntegerTextFieldValue: ObservableObject {
@Published var value = "" {
didSet {
let numbersOnly = value.filter { $0.isNumber }
if value != numbersOnly {
value = numbersOnly
}
if let number = Int(value) {
numberValue = number
}
}
}
@Published var numberValue: Int = 0
}
struct IntegerTextField: View {
@Binding var value: Int?
@StateObject private var fieldValue = IntegerTextFieldValue()
var placeholder = ""
var body: some View {
TextField(placeholder, text: $fieldValue.value)
.keyboardType(.numberPad)
.onAppear {
if let value = value {
fieldValue.value = "\(value)"
}
}
.onChange(of: fieldValue.numberValue) {
if $0 != self.value {
self.value = $0
}
}
}
}
onChange
принимает значение, а не привязку. Однако ваш ответ здесь, по сути, дал мне то, что мне нужно, используя.onChange(of: fieldValue.value) { value = Int($0) }