SwiftUI / .onDelete 嵌套数组列表中的子 OutlineGroup 行
SwiftUI / .onDelete child OutlineGroup row in a List from a nested array
我正在创建一个使用 OutlineGroup 呈现嵌套数组的列表。我正在尝试对此 ForEach 循环实施 .onDelete。
Interface UI
.onDelete 在此 ForEach 循环中无法正常工作。
可以正确删除顶级行,但不能正确删除子级行。
我认为 IndexSet 没有正确定位 focusExample[subFocus]。
(当我尝试时出现错误)
如何让 .onDelete 在此 OutlineGroup 中正常工作?
struct FocusArea: Identifiable {
let id = UUID()
let focus: String
let time: Int
let subFocus: [FocusArea]?
}
struct FocusView: View {
@State private var focusExample =
[ FocusArea(focus: "PhD", time: 20, subFocus: [
FocusArea(focus: "Experimenting", time: 15, subFocus: nil),
FocusArea(focus: "Writing", time: 5, subFocus: nil)
]),
FocusArea(focus: "Reading", time: 10, subFocus:[
FocusArea(focus: "Holes", time: 7, subFocus: nil),
FocusArea(focus: "Harry Potter", time: 3, subFocus: nil)
]),
FocusArea(focus: "Piano", time: 5, subFocus: nil)
]
func delete(at offset: IndexSet) {
focusExample.remove(atOffsets: offset)
}
var body: some View {
NavigationView{
List{
ForEach(focusExample) { focus in
OutlineGroup(focus, children: \.subFocus) { subFocus in
HStack {
Text(subFocus.focus)
Spacer()
Group {
Text("\(focus.time)")
.font(Font.system(.body, design: .rounded).weight(.medium))
+
Text(" HR")
.font(Font.system(.body, design: .rounded).weight(.medium).smallCaps())
}.foregroundColor(Color.green)
}
}
}.onDelete(perform: delete)
}
.toolbar {
EditButton()
}
.navigationTitle("Focus")
}
}
}
OutlineGroup
本身就是一个完整的视图。它不需要 ForEach
围绕它。
(实际上,在您的代码中,您可以删除 ForEach
,一切都会照常进行。)
这也意味着,(到目前为止)它不处理编辑模式,也不处理 .onDelete
。
但是:如果您只需要两个层级(父级 - 子级),您可以使用 ForEach
和 DisclosureGroup
来实现并获得您想要的结果:)
var body: some View {
NavigationView{
List{
// outer ForEach for parents, binding! for delete to work
ForEach($focusExample) { $focus in
DisclosureGroup {
// Inner ForEach for children
ForEach(focus.subFocus ?? []) { subFocus in
focusCell(focus: subFocus)
}
.onDelete { indices in
// delete for children
focus.subFocus?.remove(atOffsets: indices)
}
} label: {
focusCell(focus: focus)
}
}
.onDelete { indices in
// delete for parents
focusExample.remove(atOffsets: indices)
}
}
.toolbar {
EditButton()
}
.navigationTitle("Focus")
}
}
// your original formatting, just factored out
func focusCell(focus: FocusArea) -> some View {
HStack {
Text(focus.focus)
Spacer()
Group {
Text("\(focus.time)")
.font(Font.system(.body, design: .rounded).weight(.medium))
+
Text(" HR")
.font(Font.system(.body, design: .rounded).weight(.medium).smallCaps())
}.foregroundColor(Color.green)
}
}
我正在创建一个使用 OutlineGroup 呈现嵌套数组的列表。我正在尝试对此 ForEach 循环实施 .onDelete。
Interface UI
.onDelete 在此 ForEach 循环中无法正常工作。
可以正确删除顶级行,但不能正确删除子级行。
我认为 IndexSet 没有正确定位 focusExample[subFocus]。 (当我尝试时出现错误)
如何让 .onDelete 在此 OutlineGroup 中正常工作?
struct FocusArea: Identifiable {
let id = UUID()
let focus: String
let time: Int
let subFocus: [FocusArea]?
}
struct FocusView: View {
@State private var focusExample =
[ FocusArea(focus: "PhD", time: 20, subFocus: [
FocusArea(focus: "Experimenting", time: 15, subFocus: nil),
FocusArea(focus: "Writing", time: 5, subFocus: nil)
]),
FocusArea(focus: "Reading", time: 10, subFocus:[
FocusArea(focus: "Holes", time: 7, subFocus: nil),
FocusArea(focus: "Harry Potter", time: 3, subFocus: nil)
]),
FocusArea(focus: "Piano", time: 5, subFocus: nil)
]
func delete(at offset: IndexSet) {
focusExample.remove(atOffsets: offset)
}
var body: some View {
NavigationView{
List{
ForEach(focusExample) { focus in
OutlineGroup(focus, children: \.subFocus) { subFocus in
HStack {
Text(subFocus.focus)
Spacer()
Group {
Text("\(focus.time)")
.font(Font.system(.body, design: .rounded).weight(.medium))
+
Text(" HR")
.font(Font.system(.body, design: .rounded).weight(.medium).smallCaps())
}.foregroundColor(Color.green)
}
}
}.onDelete(perform: delete)
}
.toolbar {
EditButton()
}
.navigationTitle("Focus")
}
}
}
OutlineGroup
本身就是一个完整的视图。它不需要 ForEach
围绕它。
(实际上,在您的代码中,您可以删除 ForEach
,一切都会照常进行。)
这也意味着,(到目前为止)它不处理编辑模式,也不处理 .onDelete
。
但是:如果您只需要两个层级(父级 - 子级),您可以使用 ForEach
和 DisclosureGroup
来实现并获得您想要的结果:)
var body: some View {
NavigationView{
List{
// outer ForEach for parents, binding! for delete to work
ForEach($focusExample) { $focus in
DisclosureGroup {
// Inner ForEach for children
ForEach(focus.subFocus ?? []) { subFocus in
focusCell(focus: subFocus)
}
.onDelete { indices in
// delete for children
focus.subFocus?.remove(atOffsets: indices)
}
} label: {
focusCell(focus: focus)
}
}
.onDelete { indices in
// delete for parents
focusExample.remove(atOffsets: indices)
}
}
.toolbar {
EditButton()
}
.navigationTitle("Focus")
}
}
// your original formatting, just factored out
func focusCell(focus: FocusArea) -> some View {
HStack {
Text(focus.focus)
Spacer()
Group {
Text("\(focus.time)")
.font(Font.system(.body, design: .rounded).weight(.medium))
+
Text(" HR")
.font(Font.system(.body, design: .rounded).weight(.medium).smallCaps())
}.foregroundColor(Color.green)
}
}