Свяжите @Binding с @Published с помощью SwiftUI

Я пытаюсь понять, как связать @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)"
                }
            }
    }
}
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
3
0
1 672
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Если я правильно тебя понял

.onChange (of: fieldValue.value) { vl in
    value = vl
}

этот модификатор обновляет привязку value к $fieldValue.value

onChange принимает значение, а не привязку. Однако ваш ответ здесь, по сути, дал мне то, что мне нужно, используя .onChange(of: fieldValue.value) { value = Int($0) }
Gargoyle 21.12.2020 12:12
Ответ принят как подходящий

Вот модифицированный код для демонстрации возможного подхода (проверено с помощью 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
                }
            }
    }
}

Другие вопросы по теме