有没有办法在 SwiftUI 中“取消绑定”变量/对象

Posted

技术标签:

【中文标题】有没有办法在 SwiftUI 中“取消绑定”变量/对象【英文标题】:Is there a way to "unbind" variables/objects in SwiftUI 【发布时间】:2020-09-12 13:04:39 【问题描述】:

我能做的最好的比较是所有手机都附带的 iPhone 通讯录应用程序。

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

我的应用中的一项功能完全相同。

    我向用户展示了一个列表,用户可以点击列表中的任何项目。

    点击项目后,他们可以在“详细信息视图”中查看该项目的详细信息。

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

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

再次简单,就像联系人应用程序一样。

所以问题来了:“保存”完美无缺,因为我将对象作为绑定变量传递:

@Binding var cigar: Cigar

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

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

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

能否请一些人提供帮助,或者您是否可以提出更好的方法来实现结果。

【问题讨论】:

【参考方案1】:

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

只要您有有状态编辑(即通过保存操作的事实应用),您需要明确的本地存储这些数据。

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

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
     
  

【讨论】:

我不得不改成self._editingCigar = State(initialValue: cigar.wrappedValue)(注意下划线) @Charlyberthet,是的,谢谢 - 看起来是错字

以上是关于有没有办法在 SwiftUI 中“取消绑定”变量/对象的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法只解除非命名空间事件的绑定?

SwiftUi 有没有办法在 TextField 中获取文本

SwiftUI:有没有办法创建一个单选列表(比如在 iOS 设置中)?

有没有办法在 SwiftUI 中制作分页的 ScrollView?

在 SwiftUI (Xcode 12) 中折叠侧边栏

有没有办法在 SwiftUI 中制作 List 样式 insetGrouped?