I have 2 lists in a vstack. I want to use 2 editbuttons to change the editmode of the 2 lists separately.
I know the 2 editbuttons will be associated with the same environment value of the struct EditModeInTwoLists like this:
struct EditModeInTwoLists: View {
var body: some View {
VStack{
EditButton()
List{
ForEach(1..<5){_ in
Text("List1")
}
}
EditButton()
List{
ForEach(1..<5){_ in
Text("List2")
}
}
}
}
}
Therefore, I encapsulate the lists into 2 separate childviews. Because, IMO, the 2 childviews should have separate environment value. I change the code like this:
struct EditModeInTwoLists: View {
var body: some View {
VStack{
EmbedList1()
EmbedList2()
}
}
}
struct EmbedList1: View{
var body: some View{
VStack{
EditButton()
List{
ForEach(1..<5){_ in
Text("List1")
}
}
}
}
}
struct EmbedList2: View{
var body: some View{
VStack{
EditButton()
List{
ForEach(1..<5){_ in
Text("List2")
}
}
}
}
}
However, the 2 editbuttons also toggle synchronously. Do I misunderstand anything? Is there any way to toggle the 2 editbuttons separately?
EDIT:
@Asperi 's approach works for me. However, if I customize a button to toggle the wrappedValue of editmode, the issue appears again. I don't quite understand of the reason.
struct EmbedList1: View{
@Environment(\.editMode) private var editMode
var body: some View{
VStack{
Button {
if editMode != nil{
editMode!.wrappedValue = editMode!.wrappedValue.isEditing ? .inactive : .active
}
} label: {
Text(editMode?.wrappedValue.isEditing == true ? "Done" : "Edit")
}
List{
ForEach(1..<5){_ in
Text("List1")
}
}
}
}
}
We don't know what exactly EditButton
does inside. Actually standard API is for standard things.
In such cases it is more appropriate to work with EditMode
directly to have control over it.
Here is a possible approach (tested with Xcode 13.4 / iOS 15.5)
struct EmbedList1: View{
@State var editMode: EditMode = .inactive // << own state
var body: some View{
VStack{
// own button to switch
Button(editMode == .inactive ? "Edit" : "Done") {
editMode = editMode == .active ? .inactive : .active
}
List{
ForEach(1..<5){_ in
Text("List1")
}
}
}
.environment(\.editMode, $editMode) // << own env
}
}
// do same inside EmbedList2