完成后的 SwiftUI EditButton 操作

SwiftUI EditButton action on Done

当用户点击显示为 "Done" 的 EditButton 时,如何设置要执行的操作?甚至可以这样做吗?

请注意,这与对用户可能执行的每个单独编辑执行的操作不同(如 onDeleteonMove)。当用户完成所有更改并准备好提交时,您如何设置要执行的操作?

这是必要的,因为我正在对模型的临时副本进行所有更改,并且在用户点击 "Done" 之前不会将更改提交到实际模型。我还提供了一个 "Cancel" 按钮来放弃更改。

struct MyView: View {
    @Environment(\.editMode) var mode

    var body: some View {
        VStack {
            HStack {
                if self.mode?.value == .active {
                    Button(action: {
                        // discard changes here
                        self.mode?.value = .inactive
                    }) {
                        Text("Cancel")
                    }
                }

                Spacer()

                EditButton()
                // how to commit changes??
            }
            // controls to change the model
        }
    }
}

是否可以在 EditButton 上为 "Done" 设置一个操作,或者我是否必须提供自己的按钮来像 EditButton 一样操作?我当然可以做到这一点,但使用 EditButton 似乎应该很容易做到。

您可以使用 onDisappear() 修饰符在仅在编辑模式下显示的视图上执行操作。在 SwiftUI "Working with UI Controls":

的教程中有一个关于如何做到这一点的例子
if self.mode?.wrappedValue == .inactive {
    ProfileSummary(profile: profile)
} else {
    ProfileEditor(profile: $draftProfile)
        .onDisappear {
            self.draftProfile = self.profile
        }
}

在上面的示例代码中,由于您没有在编辑模式下显示的视图,您可以添加状态来检查您是否单击了 "Cancel" 或 "Done",如下所示:

struct MyView: View {    
    @Environment(\.editMode) var mode
    @State var isCancelled = false

    var body: some View {
        VStack {
            HStack {
                if self.mode?.wrappedValue == .active {
                    Button(action: {
                            // discard changes here
                            self.mode?.wrappedValue = .inactive
                            self.isCancelled = true
                        }) {
                            Text("Cancel")
                        }
                        .onAppear() {
                            self.isCancelled = false
                        }
                        .onDisappear() {
                            if (self.isCancelled) {
                                print("Cancel")
                            } else {
                                print("Done")
                            }

                        }
                    }

                    Spacer()

                    EditButton()

                    // how to commit changes??
                }
                // controls to change the model
            }
        }
    }

您最后的评论包含对事物的细微更改。在那之前,听起来你想要 一个 "Done" 和 "Cancel" 按钮——很少有 iOS 应用程序这样做。

但是如果你想要一个带有 "double-checking things, are you sure" 的 "Done" 按钮,你应该能够通过(可能) 进入编辑模式并检测何时没有更长的时间。保存一个 "before" 状态,在即将更改时添加一个弹出窗口,你可能会给用户一个回滚选项。

仅供参考 - 我非常守旧派。不只是PC,还有大型机。不仅是微软,还有 SAP。我当然理解想要在破坏性更改之前给用户最后一次机会 - 但没有太多 iOS 应用程序这样做。 :-)

据我了解,EditButton 旨在将整个环境置于编辑模式。这意味着进入一种模式,例如,您可以重新排列或删除列表中的项目。或者文本字段变为可编辑的位置。诸如此类的事情。 "Done" 表示 "I'm done being in edit mode",而不是 "I want to apply my changes." 您可能需要一个不同的 "Apply changes," "Save," "Confirm" 或任何按钮来执行这些操作。

XCode12/iOS14 的新答案使用 onChange modifier.

此方法使用通过 @Environment 可用的 SwiftUI editMode 键路径以及新的 onChange 修饰符来确定视图何时进入和退出编辑模式。

在您看来,请执行以下操作:

@Environment(\.editMode) private var editMode

...

.onChange(of: editMode!.wrappedValue, perform: { value in 
  if value.isEditing {
     // Entering edit mode (e.g. 'Edit' tapped)
  } else {
     // Leaving edit mode (e.g. 'Done' tapped)
  }
})