【发布时间】:2021-09-04 13:36:46
【问题描述】:
对 SwiftUI 和 Swift 非常陌生,并试图将我的头脑围绕在绑定上。
具体来说,我有一个 Tasks 的 ForEach 循环,它显示了一个新的 TaskRow Tasks。该任务行有两个操作:
- 用于删除相关行中显示的任务的按钮
- 用于将任务状态从“已完成”更改为“未完成”的开关
如果没有切换,每当我删除任务时,视图都会正常更新。但是在切换存在的情况下,删除任务会引发:
Thread 1: Fatal error: Index out of range
错误。
我认为这与 $isSet 绑定到 self.$data 有关,但我不知道如何以切换将更新的方式传递该数据。代码如下,深表感谢:
TaskList.swift
import SwiftUI
struct TaskList: View {
@ObservedObject private var data = TaskData()
@State private var showFinished: Bool = false
var visibleTasks: [Task] {
data.tasks.filter { task in
showFinished || !task.finished
}
}
var body: some View {
VStack {
Toggle(isOn: $showFinished) {
Text("Show Finished")
}
ForEach(data.tasks.indices, id: \.self) { index in
TaskRow(
isSet: self.$data.tasks[index].finished,
task: self.data.tasks[index],
onChange: { self.data.save() },
onDelete: { self.deleteTask(task_index: index)})
Divider()
}
AddTask(data: data)
}
.padding()
.onAppear {
data.load()
}
}
func deleteTask(task_index: Int) {
self.data.tasks.remove(at: self.data.tasks[task_index].id)
}
}
TaskRow.swift
导入 SwiftUI
struct TaskRow: View {
@Binding var isSet: Bool
@State var task: Task
var onChange: () -> ()
var onDelete: () -> ()
var body: some View {
HStack() {
Toggle("", isOn: $isSet)
.onChange(of: isSet) { _isOn in
onChange()
}
Text(task.name)
Spacer()
Button(action: onDelete) {
Image(systemName: "minus.circle")
}
}
.scaledToFit()
}
}
【问题讨论】:
-
你应该看看 WWDC 2021 的 Demystify SwiftUI 视频。你有一些小错误。
-
嗨,PlankTon,cn,请不要将数据设为私有 var,而是设为 var?然后检查 data.tasks.indices 是否仍然没有更新。
-
@MacUserT 为什么你认为它可以改变任何东西?
-
算了,它没有。尽管如此,ObservedObject 是一个 var,而不是私有 var。
-
@MacUserT 如果您不需要为此变量生成可选的初始值设定项参数,它可以很容易地私有化。