изменение содержимого TextField
Добрый день! Недавно начал изучать SwiftUI, и столкнулся с проблемой. Начал делать конвертер величин. Хочу сделать так, чтобы при вводе значения в одно из TextField - текст в остальных TextField менялся Прошу подсказки)
import SwiftUI
import Combine
struct ContentView: View {
@State var celsius: String = ""
@State var kelvin: String = ""
@State var farenheit: String = ""
@State var reyumur: String = ""
@State var rankin: String = ""
var body: some View {
NavigationView {
Temperature(celsius: $celsius, kelvin: $kelvin, farenheit: $farenheit, reyumur: $reyumur, rankin: $rankin)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct Temperature: View {
@Binding var celsius: String
@Binding var kelvin: String
@Binding var farenheit: String
@Binding var reyumur: String
@Binding var rankin: String
var body: some View {
List {
Section(
header: Text("Международная система (СИ)")) {
HStack {
TextField("Введите значение", text: $celsius)
.keyboardType(.numbersAndPunctuation)
.onReceive(Just(celsius)) { newValue in
let filtered = newValue.filter { "0123456789.".contains($0) }
if filtered != newValue {
self.celsius = filtered
}
}
Text("°C")
.padding(.horizontal)
.font(.headline)
.foregroundColor(.blue)
}
HStack {
TextField("Введите значение", text: $kelvin)
.keyboardType(.numbersAndPunctuation)
.onReceive(Just(kelvin)) { newValue in
let filtered = newValue.filter { "0123456789.".contains($0) }
if filtered != newValue {
self.kelvin = filtered
}
}
Text("K")
.padding(.horizontal)
.font(.headline)
.foregroundColor(.blue)
}
}
Section(
header: Text("США и Британия")) {
HStack {
TextField("Введите значение" , text: $farenheit)
.keyboardType(.numbersAndPunctuation)
.onReceive(Just(farenheit)) { newValue in
let filtered = newValue.filter { "0123456789.".contains($0) }
if filtered != newValue {
self.farenheit = filtered
}
}
Text("F")
.padding(.horizontal)
.font(.headline)
.foregroundColor(.blue)
}
}
Section(
header: Text("Редкоиспользуемые")) {
HStack {
TextField("Введите значение" , text: $reyumur)
.keyboardType(.numbersAndPunctuation)
.onReceive(Just(reyumur)) { newValue in
let filtered = newValue.filter { "0123456789.".contains($0) }
if filtered != newValue {
self.reyumur = filtered
}
}
Text("Re")
.padding(.horizontal)
.font(.headline)
.foregroundColor(.blue)
}
HStack {
TextField("Введите значение" , text: $rankin)
.keyboardType(.numbersAndPunctuation)
.onReceive(Just(rankin)) { newValue in
let filtered = newValue.filter { "0123456789.".contains($0) }
if filtered != newValue {
self.rankin = filtered
}
}
Text("R")
.padding(.horizontal)
.font(.headline)
.foregroundColor(.blue)
}
}
}
.navigationBarTitle("Температура")
.navigationBarTitleDisplayMode(.inline)
}
}
Ответы (1 шт):
Автор решения: Andrew
→ Ссылка
В даном случае тебе желательно все сделать через модель.
Это делается как-то так:
public class TemperatureViewModel: ObservableObject {
var blockedChanges = false
@Published var celsius: String { didSet { celsiusChanged() } }
@Published var kelvin: String { didSet { kelvinChanged() } }
@Published var farenheit: String { didSet { farenheitChanged() } }
@Published var reyumur: String { didSet { reyumurChanged() } }
@Published var rankin: String { didSet { rankinChanged() } }
func celsiusChanged() {
if self.blockedChanges == true { return }
self.blockedChanges = true
//здесь меняй все переменные
self.blockedChanges = false
}
func kelvinChanged() {
if self.blockedChanges == true { return }
self.blockedChanges = true
//здесь меняй все переменные
self.blockedChanges = false
}
func farenheitChanged() {
if self.blockedChanges == true { return }
self.blockedChanges = true
//здесь меняй все переменные
self.blockedChanges = false
}
func reyumurChanged() {
if self.blockedChanges == true { return }
self.blockedChanges = true
//здесь меняй все переменные
self.blockedChanges = false
}
func rankinChanged() {
if self.blockedChanges == true { return }
self.blockedChanges = true
//здесь меняй все переменные
self.blockedChanges = false
}
}
твою вьюху полностью изменять не буду, только главное:
struct ContentView: View {
var temperatureVm = TemperatureViewModel()
var body: some View {
NavigationView {
Temperature(model: temperatureVm)
}
}
}
struct Temperature: View {
@ObservedObject model
var body: some View {
List {
.......
}
остальное поменяй сам
флаг blockedChanges необходим что бы твоя программа не ушла в вечный цикл.
еще желательно ознакомится с вот этим: https://stackoverflow.com/questions/56561630/swiftui-forcing-an-update/62919526#62919526
