具有多个编辑按钮的 SwiftUI 表单
Posted
技术标签:
【中文标题】具有多个编辑按钮的 SwiftUI 表单【英文标题】:SwiftUI Form with Multiple EditButtons 【发布时间】:2021-05-15 18:26:24 【问题描述】:试图让Form
有多个部分,每个Section
都有自己的EditButton
。
如何在不触发Form
中的所有部分的情况下触发Section
进入“编辑模式”,如随附的gif 所示。
如何跟踪某个Section
中的EditButton
是否被触发,从而Button
出现在那个Section
中。
我使用了这两个来源的代码: developer.apple.com, ***.com
代码如下:
import SwiftUI
struct ContentView: View
@Environment(\.editMode) private var editMode
@State private var section1: [String] = ["Item 1", "Item 2"]
@State private var section2: [String] = ["Item 3", "Item 4"]
@State private var isEditingSection1 = false
@State private var isEditingSection2 = false
var body: some View
Form
// Section 1
Section (header:
EditButton().frame(maxWidth: .infinity, alignment: .trailing)
.overlay(
HStack
Image(systemName: "folder")
.foregroundColor(Color.gray)
Text("Section 1")
.textCase(.none)
.foregroundColor(Color.gray)
, alignment: .leading)
.foregroundColor(.blue))
ForEach(section1, id: \.self) item in
Text(item)
.onDelete(perform: deleteSection1)
.onMove(perform: moveSection1)
// Add item option
if editMode?.wrappedValue.isEditing ?? true /*isEditingSection1*/
Button ("Add Item")
// add action
// Section 2
Section (header:
EditButton().frame(maxWidth: .infinity, alignment: .trailing)
.overlay(
HStack
Image(systemName: "tray")
.foregroundColor(Color.gray)
Text("Section 2")
.textCase(.none)
.foregroundColor(Color.gray)
, alignment: .leading)
.foregroundColor(.blue))
ForEach(section2, id: \.self) item in
Text(item)
.onDelete(perform: deleteSection2)
.onMove(perform: moveSection2)
// Add item option
if editMode?.wrappedValue.isEditing ?? true /*isEditingSection2*/
Button ("Add Item")
// add action
func deleteSection1(at offsets: IndexSet)
section1.remove(atOffsets: offsets)
func moveSection1(from source: IndexSet, to destination: Int)
section1.move(fromOffsets: source, toOffset: destination)
func deleteSection2(at offsets: IndexSet)
section2.remove(atOffsets: offsets)
func moveSection2(from source: IndexSet, to destination: Int)
section2.move(fromOffsets: source, toOffset: destination)
struct ContentView_Previews: PreviewProvider
static var previews: some View
ContentView()
【问题讨论】:
【参考方案1】:没有内置的东西可以为每个部分设置不同的编辑模式。
但您可以显式使用它来设置编辑模式并禁用/启用每行的删除和移动操作。
这是可能的解决方案演示。
为此,您需要首先使用绑定 bool 值创建自己的 EditButton。
struct EditButton: View
@Binding var isEditing: Bool
var body: some View
Button(isEditing ? "DONE" : "EDIT")
withAnimation
isEditing.toggle()
现在你的Form
视图是。
struct ContentViewEditModeDemo: View
@State private var section1: [String] = ["Item 1", "Item 2"]
@State private var section2: [String] = ["Item 3", "Item 4"]
@State private var isEditingSection1 = false
@State private var isEditingSection2 = false
private var isEditingOn: Bool //<=== Here
isEditingSection1 || isEditingSection2
var body: some View
Form
// Section 1
Section (header:
EditButton(isEditing: $isEditingSection1).frame(maxWidth: .infinity, alignment: .trailing) //<=== Here
.overlay(
HStack
Image(systemName: "folder")
.foregroundColor(Color.gray)
Text("Section 1")
.textCase(.none)
.foregroundColor(Color.gray)
, alignment: .leading)
.foregroundColor(.blue))
ForEach(section1, id: \.self) item in
Text(item)
.onDelete(perform: deleteSection1)
.onMove(perform: moveSection1)
.moveDisabled(!isEditingSection1) //<=== Here
.deleteDisabled(!isEditingSection1) //<=== Here
// Add item option
if isEditingSection1 //<=== Here
Button ("Add Item")
// add action
// Section 2
Section(header:
EditButton(isEditing: $isEditingSection2).frame(maxWidth: .infinity, alignment: .trailing) //<=== Here
.overlay(
HStack
Image(systemName: "tray")
.foregroundColor(Color.gray)
Text("Section 2")
.textCase(.none)
.foregroundColor(Color.gray)
, alignment: .leading)
.foregroundColor(.blue))
ForEach(section2, id: \.self) item in
Text(item)
.onDelete(perform: deleteSection1)
.onMove(perform: moveSection1)
.moveDisabled(!isEditingSection2) //<=== Here
.deleteDisabled(!isEditingSection2) //<=== Here
// Add item option
if isEditingSection2 //<=== Here
Button ("Add Item")
// add action
.environment(\.editMode, isEditingOn ? .constant(.active) : .constant(.inactive)) //<=== Here
func deleteSection1(at offsets: IndexSet)
section1.remove(atOffsets: offsets)
func moveSection1(from source: IndexSet, to destination: Int)
section1.move(fromOffsets: source, toOffset: destination)
func deleteSection2(at offsets: IndexSet)
section2.remove(atOffsets: offsets)
func moveSection2(from source: IndexSet, to destination: Int)
section2.move(fromOffsets: source, toOffset: destination)
【讨论】:
以上是关于具有多个编辑按钮的 SwiftUI 表单的主要内容,如果未能解决你的问题,请参考以下文章