描述:
我有一个具有以下层次结构的模型:
- 食谱
- ...步骤(一个数组)
- ...当前步骤
- ......参数(一个数组)
- .........最低限度
- .........最大
- .........默认
- .........当前
该模型运行良好。我可以添加步骤、参数,并将当前步骤设置为@EnvironmentObject
被调用的recipe
.
我在这里创建了一个示例项目,其中包含两个步骤和参数列表,以及三个按钮,用于在三个硬编码步骤中添加一个步骤,每个步骤包含一个 0、1 或 3 个参数的数组。
顶部列表是步骤行,每个都是填充底部列表的按钮。底部列表是参数列表,每个列表都包含一个标签和一个滑块VStack
。
一切正常,除非我 (a) 将滑块绑定到我的模型并且(b) 列表包含的滑块(行)比当前步骤现在拥有的更多。我得到一个index out of range error
.
如果我将滑块值绑定到局部变量,则一切正常。以下是相关代码:
class Recipe: BindableObject {
var didChange = PassthroughSubject<Void, Never>()
var currentStep = Step() {
didSet {
didChange.send(())
}
}
}
struct Parameter: Identifiable {
var id:Int = 0
var name = ""
var minimum:Float = 0
var maximum:Float = 100
var `default`:Float = 30
var current:Float = 30
}
struct StepRow: View {
@EnvironmentObject var recipe: Recipe
var step: Step!
init(step: Step) {
self.step = step
}
var body: some View {
Button(action: {
self.setCurrentStep()
}) {
HStack {
Text(step.name).font(Font.body.weight(.bold))
}.frame(height: 50)
}
}
func setCurrentStep() {
recipe.currentStep = step
}
}
struct ParameterRow: View {
@EnvironmentObject var recipe: Recipe
@State var sliderValue:Float = 30
var parameter: Parameter!
init(parameter: Parameter) {
self.parameter = parameter
}
var body: some View {
VStack {
Text(parameter.name)
Slider(
// This works, swap these two lines to duplicate the index out of range error by:
// - Adding step 1, step 2, step 3, and finally step 4
// - Tapping each step in the step list in order, the first three will work but the last one won't
//value: $recipe.currentStep.parameters[parameter.id].current,
value: self.$sliderValue,
from: parameter.minimum,
through: parameter.maximum,
by: 1.0
)
}
}
}
struct ContentView : View {
@EnvironmentObject var recipe: Recipe
var body: some View {
VStack {
List {
ForEach(recipe.steps) { step in
StepRow(step: step)
}
}
List {
ForEach(recipe.currentStep.parameters) { parameter in
ParameterRow(parameter: parameter)
}
}
}
}
}
同样,一个工作示例是 project here。