使用 SwiftUI 离开视图时,如何以编程方式使列表的 editMode 处于非活动状态?

vma*_*let 4 swift swiftui

给定一个带有 EditButton() 的列表视图,如果正在编辑该视图(用户点击“编辑”按钮),当用户离开该视图时,如何以编程方式禁用编辑模式?(例如,与 iPhone 上的“电话”应用程序中的“收藏夹”视图类似的行为)

struct ContentView2: View {
    @State var fruits = ["Apple", "Banana"]

    var body: some View {
        NavigationView {
            List {
                ForEach(fruits, id: \.self) { fruit in
                    Text(fruit)
                }
                .onDelete { _ in
                    print("Delete")
                }
            }
            .toolbar {
                EditButton()
            }
        }
        .onDisappear {
            // make List's editMode be .inactive; how?
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

ahe*_*eze 7

您可以使用属性.environment来绑定列表的当前编辑模式@State,如这篇精彩文章中所示。

struct ContentView: View {
    @State var editMode = EditMode.inactive /// the edit mode

    @State var fruits = ["Apple", "Banana"]
    
    var body: some View {
        NavigationView {
            List {
                ForEach(fruits, id: \.self) { fruit in
                    Text(fruit)
                }
                .onDelete { _ in
                    print("Delete")
                }
            }
            .toolbar {
                EditButton()
            }
            .environment(\.editMode, $editMode) /// bind it here!
        }
        .onDisappear {
            editMode = .inactive /// set to inactive
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

另外,如果您使用 a来呈现新视图,则onDisappear不会调用您的 ,因为您附加到的视图实际上不会消失。您应该将其附加到 的标签上(来自此答案)。NavigationLinkNavigationViewNavigationLink

最终代码:

struct ContentView: View {
    @State var editMode = EditMode.inactive /// the edit mode
    @State var fruits = ["Apple", "Banana"]
    
    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination:  Text("New view!")) {
                    Text("Navigate away")
                        .onDisappear {
                            editMode = .inactive /// set to inactive
                        }
                }
                
                List {
                    ForEach(fruits, id: \.self) { fruit in
                        Text(fruit)
                    }
                    .onDelete { _ in
                        print("Delete")
                    }
                }
                .toolbar {
                    EditButton()
                }
                .environment(\.editMode, $editMode) /// bind it here!
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

结果:

没有 editMode = .inactive editMode = .inactive
呈现新视图并返回后列表保持编辑模式 列表在呈现新视图并返回后退出编辑模式

  • 太棒了,谢谢。事实证明我尝试过类似的方法,但我在工具栏/按钮之前添加了`.environment(\.editMode, $editMode)`,这破坏了按钮。添加按钮后进行绑定是幸福的关键。对于未来的读者来说很高兴知道。 (2认同)