iOS 16 更新:
我希望我知道why,但在 iOS 16 中你必须像这样表达布尔表达式。
.deleteDisabled(isEditingSection2)
.deleteDisabled((isEditingSection2 || isEditingSection3))
// Etc...
在 iOS 15.5 中,你可以选择其中任何一个。
.deleteDisabled(!isEditingSection1)
// Or...
.deleteDisabled(isEditingSection2)
这是一个完整的ContentView
and EditButton
显示这个。我添加了第三部分来帮助演示如何在内部应用布尔 OR 逻辑.deleteDisabled
and .moveDisabled
.
import SwiftUI
struct ContentView: View {
@State private var section1: [String] = ["Item 1", "Item 2"]
@State private var section2: [String] = ["Item 3", "Item 4"]
@State private var section3: [String] = ["Item 5", "Item 6"]
@State private var isEditingSection1 = false
@State private var isEditingSection2 = false
@State private var isEditingSection3 = false
private var isEditingOn: Bool { //<=== Here
isEditingSection1 || isEditingSection2 || isEditingSection3
}
var body: some View {
Form {
// Section 1
Section (header:
EditButton(isEditing: $isEditingSection1, printBools: printBools)
.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)
.moveDisabled(isEditingSection2 || isEditingSection3) //<=== Here
.deleteDisabled((isEditingSection2 || isEditingSection3)) //<=== Here
// BIG NOTE!!
// This works in iOS 15.5, but not iOS 16: `.deleteDisabled(!isEditingSection1)`
// This works in both 15.5 and 16.0. Why??? `.deleteDisabled(isEditingSection2 || isEditingSection3)`
// Add item option
if isEditingSection1 { //<=== Here
Button ("Add Item") {
// add action
}
}
}
// Section 2
Section(header:
EditButton(isEditing: $isEditingSection2, printBools: printBools)
.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)
.moveDisabled(isEditingSection1 || isEditingSection3) //<=== Here
.deleteDisabled(isEditingSection1 || isEditingSection3) //<=== Here
// Add item option
if isEditingSection2 { //<=== Here
Button ("Add Item") {
// add action
}
}
}
// Section 3
Section(header:
EditButton(isEditing: $isEditingSection3, printBools: printBools)
.frame(maxWidth: .infinity, alignment: .trailing)
.overlay(
HStack {
Image(systemName: "tray")
.foregroundColor(Color.gray)
Text("Section 3")
.textCase(.none)
.foregroundColor(Color.gray)
}, alignment: .leading)
.foregroundColor(.blue)) {
ForEach(section3, id: \.self) { item in
Text(item)
}
.onDelete(perform: deleteSection3)
.onMove(perform: moveSection3)
.moveDisabled(isEditingSection1 || isEditingSection2) //<=== Here
.deleteDisabled(isEditingSection1 || isEditingSection2) //<=== Here
// Add item option
if isEditingSection3 { //<=== 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)
}
func deleteSection3(at offsets: IndexSet) {
section3.remove(atOffsets: offsets)
}
func moveSection3(from source: IndexSet, to destination: Int) {
section3.move(fromOffsets: source, toOffset: destination)
}
func printBools() {
// let _ = print("isEditingSection1 = \(isEditingSection1)")
// let _ = print("isEditingSection2 = \(isEditingSection2)")
}
}
struct EditButton: View {
@Binding var isEditing: Bool
let printBools: () -> Void
var body: some View {
Button(isEditing ? "DONE" : "EDIT") {
printBools()
withAnimation {
isEditing.toggle()
}
printBools()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
注意逻辑上这里,两个表达式!isEditingSection1
and isEditingSection2 || isEditingSection3
当我们考虑如何在这里使用它们时,它们是等效的。
isEditingSection1 |
! isEditingSection1 |
isEditingSection2 OR isEditingSection3 |
true |
false |
false |
false |
true |
true , if editing another section. Otherwise false . |