SwiftUI 如何在 EditMode 更改时执行操作?
SwiftUI how to perform action when EditMode changes?
我想在 EditMode 更改时执行操作。
具体来说,在编辑模式下,用户可以select删除一些项目。他通常会在之后按下垃圾桶按钮。但他也可以按“完成”。当他稍后再次按“编辑”时,之前 selected 的项目仍然 selected。我想清除所有项目。
struct ContentView: View {
@State var isEditMode: EditMode = .inactive
@State var selection = Set<UUID>()
var items = [Item(), Item(), Item(), Item(), Item()]
var body: some View {
NavigationView {
List(selection: $selection) {
ForEach(items) { item in
Text(item.title)
}
}
.navigationBarTitle(Text("Demo"))
.navigationBarItems(
leading: EditButton(),
trailing: addDelButton
)
.environment(\.editMode, self.$isEditMode)
}
}
private var addDelButton: some View {
if isEditMode == .inactive {
return Button(action: reset) {
Image(systemName: "plus")
}
} else {
return Button(action: reset) {
Image(systemName: "trash")
}
}
}
private func reset() {
selection = Set<UUID>()
}
}
项目定义:
struct Item: Identifiable {
let id = UUID()
let title: String
static var i = 0
init() {
self.title = "\(Item.i)"
Item.i += 1
}
}
更新 iOS 15.
此解法一石二鸟:
- 当 editMode 为 toggle 时,整个视图会自行重绘
- 可以在 editModeactivation/inactivation 上执行特定操作
希望这对其他人有帮助。
struct ContentView: View {
@State var editMode: EditMode = .inactive
@State var selection = Set<UUID>()
@State var items = [Item(), Item(), Item()]
var body: some View {
NavigationView {
List(selection: $selection) {
ForEach(items) { item in
Text(item.title)
}
}
.navigationTitle(Text("Demo"))
.environment(\.editMode, self.$editMode)
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
editButton
}
ToolbarItem(placement: .navigationBarTrailing) {
addDelButton
}
}
}
}
private var editButton: some View {
Button(action: {
self.editMode.toggle()
self.selection = Set<UUID>()
}) {
Text(self.editMode.title)
}
}
private var addDelButton: some View {
if editMode == .inactive {
return Button(action: addItem) {
Image(systemName: "plus")
}
} else {
return Button(action: deleteItems) {
Image(systemName: "trash")
}
}
}
private func addItem() {
items.append(Item())
}
private func deleteItems() {
for id in selection {
if let index = items.lastIndex(where: { [=10=].id == id }) {
items.remove(at: index)
}
}
selection = Set<UUID>()
}
}
extension EditMode {
var title: String {
self == .active ? "Done" : "Edit"
}
mutating func toggle() {
self = self == .active ? .inactive : .active
}
}
我想在 EditMode 更改时执行操作。
具体来说,在编辑模式下,用户可以select删除一些项目。他通常会在之后按下垃圾桶按钮。但他也可以按“完成”。当他稍后再次按“编辑”时,之前 selected 的项目仍然 selected。我想清除所有项目。
struct ContentView: View {
@State var isEditMode: EditMode = .inactive
@State var selection = Set<UUID>()
var items = [Item(), Item(), Item(), Item(), Item()]
var body: some View {
NavigationView {
List(selection: $selection) {
ForEach(items) { item in
Text(item.title)
}
}
.navigationBarTitle(Text("Demo"))
.navigationBarItems(
leading: EditButton(),
trailing: addDelButton
)
.environment(\.editMode, self.$isEditMode)
}
}
private var addDelButton: some View {
if isEditMode == .inactive {
return Button(action: reset) {
Image(systemName: "plus")
}
} else {
return Button(action: reset) {
Image(systemName: "trash")
}
}
}
private func reset() {
selection = Set<UUID>()
}
}
项目定义:
struct Item: Identifiable {
let id = UUID()
let title: String
static var i = 0
init() {
self.title = "\(Item.i)"
Item.i += 1
}
}
更新 iOS 15.
此解法一石二鸟:
- 当 editMode 为 toggle 时,整个视图会自行重绘
- 可以在 editModeactivation/inactivation 上执行特定操作
希望这对其他人有帮助。
struct ContentView: View {
@State var editMode: EditMode = .inactive
@State var selection = Set<UUID>()
@State var items = [Item(), Item(), Item()]
var body: some View {
NavigationView {
List(selection: $selection) {
ForEach(items) { item in
Text(item.title)
}
}
.navigationTitle(Text("Demo"))
.environment(\.editMode, self.$editMode)
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
editButton
}
ToolbarItem(placement: .navigationBarTrailing) {
addDelButton
}
}
}
}
private var editButton: some View {
Button(action: {
self.editMode.toggle()
self.selection = Set<UUID>()
}) {
Text(self.editMode.title)
}
}
private var addDelButton: some View {
if editMode == .inactive {
return Button(action: addItem) {
Image(systemName: "plus")
}
} else {
return Button(action: deleteItems) {
Image(systemName: "trash")
}
}
}
private func addItem() {
items.append(Item())
}
private func deleteItems() {
for id in selection {
if let index = items.lastIndex(where: { [=10=].id == id }) {
items.remove(at: index)
}
}
selection = Set<UUID>()
}
}
extension EditMode {
var title: String {
self == .active ? "Done" : "Edit"
}
mutating func toggle() {
self = self == .active ? .inactive : .active
}
}