有没有办法在SwiftUI

时间:2020-09-12 13:04:39

标签: ios data-binding swiftui

我能做的最好的比较是所有手机随附的iPhone Contacts应用程序。

当用户启动应用程序时,它将列出所有联系人。用户可以选择一个联系人,并显示该联系人的“详细信息视图”。最后,用户可以选择编辑联系人并进入“编辑详细信息视图”。简单...

我的应用程序具有的功能之一完全相同。

  1. 我向用户显示了一个列表,用户可以单击列表上的任何项目。

  2. 一旦他们单击该项目,便可以在“详细信息视图”上查看该项目的详细信息。

  3. 用户可以“编辑”项目,现在他们可以通过“编辑详细信息视图”中的文本字段输入对项目的修改。

  4. 用户现在可以根据需要“保存”或“取消”他们的修改/编辑,这会将他们导航回“详细信息视图”。

就像“通讯录”应用一样,再次获得简单的体验。

这就是问题所在:因为我将对象作为绑定变量传递,所以“保存”的工作无懈可击:

@Binding var cigar: Cigar

当更改文本字段时,修改将在用户按下“保存”后反映在“详细信息视图”中的更改,这是期望的结果。

问题是,即使用户单击“取消”,文本字段中的更改仍被引用-取消引用的“保存”,这不是期望的结果。我想那是因为我正在使用@Binding变量,并且该变量实时更改。

所以我的问题是,当用户单击“取消”或想要放弃所做的更改/编辑时,是否有任何方法可以“取消绑定”或放弃对@Binding变量/对象所做的更改?

请提供一些帮助,或者您可以提出一种更好的方法来达到目标​​。

1 个答案:

答案 0 :(得分:0)

绑定是对真相来源的直接引用,因此进行编辑时,您将直接修改原始数据,因此在取消时(即在应用了 之后)进行未绑定即使有可能也没有意义(但事实并非如此)。

只要您进行了有状态编辑(即通过保存操作的事实进行应用),就需要为这些数据提供显式的本地存储。

这是一种可能的方法(用伪代码)

struct SomeView: View {

   @Binding var cigar: Cigar

   @State private var editingCigar: Cigar

   init(cigar: Binding<Cigar>) {
      self._cigar = cigar
      self.editingCigar = State(initialValue: cigar.wrappedValue)
   }

   var body: some View {

     // ... work here with `editingCigar`

     Button("Save") { 
        // !! Copy back edited cigar explicitly
        self.cigar = editingCigar
     }

     Button("Cancel") {
        // just close w/o touching self.cigar
     }
  }
}