Я пытаюсь заставить Пикер динамически обновляться в зависимости от выбора предыдущего Пикера. Для этого я использую многомерный массив. К сожалению, это, кажется, смущает мой цикл ForEach, и я заметил следующее сообщение в журналах:
ForEach<Range<Int>, Int, Text> count (3) != its initial count (5).
ForEach (: content:) should only be used for *constant* data. Instead conform data to
Идентифицируемый or use
ForEach (: id: content:) and provide an explicit
id !
Это имеет смысл, я предполагаю, что происходит то, что я передаю ему один массив, и он продолжает ссылаться на него, насколько это возможноэто постоянно меняется, когда я передаю ему другой массив. Я считаю, что способ решить эту проблему - использовать параметр id, который можно передать в ForEach, хотя я не уверен, что это действительно решит проблему, и я не уверен, что бы я использовал. Другим решением было бы как-то уничтожить сборщик и воссоздать его? Есть идеи?
Мой код следующий. Если вы запустите его, вы заметите, что перемещение вокруг первого средства выбора может привести к исключению за пределами границ.
import SwiftUI
struct ContentView: View {
@State private var baseNumber = ""
@State private var dimensionSelection = 1
@State private var baseUnitSelection = 0
@State private var convertedUnitSelection = 0
let temperatureUnits = ["Celsius", "Fahrenheit", "Kelvin"]
let lengthUnits = ["meters", "kilometers", "feet", "yards", "miles"]
let timeUnits = ["seconds", "minutes", "hours", "days"]
let volumeUnits = ["milliliters", "liters", "cups", "pints", "gallons"]
let dimensionChoices = ["Temperature", "Length", "Time", "Volume"]
let dimensions: [[String]]
init () {
dimensions = [temperatureUnits, lengthUnits, timeUnits, volumeUnits]
}
var convertedValue: Double {
var result: Double = 0
let base = Double(baseNumber) ?? 0
if temperatureUnits[baseUnitSelection] == "Celsius" {
if convertedUnitSelection == 0 {
result = base
} else if convertedUnitSelection == 1 {
result = base * 9/5 + 32
} else if convertedUnitSelection == 2 {
result = base + 273.15
}
}
return result
}
var body: some View {
NavigationView {
Form {
Section {
TextField("Enter a number", text: $baseNumber)
.keyboardType(.decimalPad)
}
Section(header: Text("Select the type of conversion")) {
Picker("Dimension", selection: $dimensionSelection) {
ForEach(0 ..< dimensionChoices.count) {
Text(self.dimensionChoices[$0])
}
}.pickerStyle(SegmentedPickerStyle())
}
Group {
Section(header: Text("Select the base unit")) {
Picker("Base Unit", selection: $baseUnitSelection) {
ForEach(0 ..< self.dimensions[self.dimensionSelection].count) {
Text(self.dimensions[self.dimensionSelection][$0])
}
}.pickerStyle(SegmentedPickerStyle())
}
Section(header: Text("Select the unit to convert to")) {
Picker("Converted Unit", selection: $convertedUnitSelection) {
ForEach(0 ..< self.dimensions[self.dimensionSelection].count) {
Text(self.dimensions[self.dimensionSelection][$0])
}
}.pickerStyle(SegmentedPickerStyle())
}
}
Section(header: Text("The converted value is")) {
Text("\(convertedValue) \(dimensions[dimensionSelection][convertedUnitSelection])")
}
}.navigationBarTitle("Unit Converter")
}
}
}