Ios 将BindableObject传递给视图

Ios 将BindableObject传递给视图,ios,swiftui,swift5.1,Ios,Swiftui,Swift5.1,在Apple的会话和教程中,我们有两个选项可以将BindableObject传递给视图 使用declareBindableObject作为层次结构中带有@ObjectBinding包装器的顶层视图中的真理源,并将其传递给声明了@Binding的其他视图 在带有@environmentobject包装器的层次结构的顶部视图中,使用declareBindableObject作为真理的来源,使用.environment(BindableObject)修饰符初始化顶部视图,并将其传递给其他视图或声明了@

在Apple的会话和教程中,我们有两个选项可以将BindableObject传递给视图

  • 使用declare
    BindableObject
    作为层次结构中带有
    @ObjectBinding
    包装器的顶层视图中的真理源,并将其传递给声明了
    @Binding
    的其他视图
  • 在带有
    @environmentobject
    包装器的层次结构的顶部视图中,使用declare
    BindableObject
    作为真理的来源,使用
    .environment(BindableObject)
    修饰符初始化顶部视图,并将其传递给其他视图或声明了
    @Binding
    或使用
    @environmentobject
    (在这种情况下,
    BindableObject
    将由SwiftUI自动分配,我们不需要在init上传递它)
  • 如果我们有
    BindableObject
    中的项目列表,并且我们想要更改其他视图(或RowView,甚至单独屏幕)上的一个项目,我们需要:

  • 使用上述任何一种方法将
    BindableObject
    传递到更深的视图。
  • 将所选项目传递到此视图
  • 通过在
    BindableObject
    列表中查找项,使用
    BindingView
    绑定项的属性
  • 一些代码可以让问题变得清晰:

    消息模型和
    BindableObject

    struct Message: Identifiable {
        var id: String
        var toggle: Bool = true
    }
    
    class MessageStore: BindableObject {
    
      let didChange = PassthroughSubject<MessageStore, Never>()
    
      var messagesList: [Message] = testData {
        didSet {
          didChange.send(self)
        }
      }
    }
    
    struct MessageRow: View {
    
        @EnvironmentObject var tags: MessageStore
        var message: Message
    
        var messageIndex: Int {
            tags.messagesList.firstIndex { $0.id == message.id }!
        }
    
    
        var body: some View {
           Toggle(isOn: self.$tags.messagesList[self.messageIndex].toggle) {
               Text("Test toogle")
           }
        }
    
    }
    
    MessageRow,具有用于更新特定项目输入输出状态的开关
    BindableObject

    struct Message: Identifiable {
        var id: String
        var toggle: Bool = true
    }
    
    class MessageStore: BindableObject {
    
      let didChange = PassthroughSubject<MessageStore, Never>()
    
      var messagesList: [Message] = testData {
        didSet {
          didChange.send(self)
        }
      }
    }
    
    struct MessageRow: View {
    
        @EnvironmentObject var tags: MessageStore
        var message: Message
    
        var messageIndex: Int {
            tags.messagesList.firstIndex { $0.id == message.id }!
        }
    
    
        var body: some View {
           Toggle(isOn: self.$tags.messagesList[self.messageIndex].toggle) {
               Text("Test toogle")
           }
        }
    
    }
    
    我上面提到的教程中显示了这种方法

    问题: 我想将消息作为
    @Binding
    单独传递,以便在子视图中直接使用它,但我无法实现这一点。
    我感到有点困惑。传递到任何视图(应该处理绑定)的
    BindableObject
    和所选项目是否都是正确的方法,以便稍后使用索引绑定
    BindableObject
    中的项目?是否有其他方法允许传递的不是完整的
    BindableObject
    ,而是它的一部分并绑定此部分(这应该是真相的来源),在我们的例子中,这部分是
    消息

    我认为你把它复杂化了。似乎你所需要的只是消息中的一个切换值。试试这个:

    var body: some View {
        NavigationView {
            List(messageStore.messagesList) { message in
                NavigationButton(destination: Text(message.id)) {
                    MessageRow(isTogged: $message.toggle)
                }
            }
            .navigationBarTitle(Text("Messages"))
        }
    }
    
    struct MessageRow: View {
    
        @Binding var isToggled: Bool
    
        var body: some View {
            Toggle(isOn: self.isToggled) {
                Text("Test toogle")
            }
        }
    }
    

    您不能这样做。MessageRow(isTogged:$message.toggle)将建议您删除$,因为本地消息不是可绑定的。更真实的情况是,消息包含一些字符串字段和切换,并且所有这些字段都可以在子视图中编辑。我认为在这种情况下,我们不能为每个字段创建
    @Binding
    ,但我们也不能使用
    @Binding
    var message:MessageHmm,我看过了你提到的教程。他们创建了BindableObject类来监视对模型的更改。如果你添加了该功能并省略了$sign,你在子视图中所做的更改将自动添加并与你的模型同步。看起来你误解了我在他们教程中提出的问题,我有一个完整的BindableObject和子对象n BindableObject中的数组。为了使其与子视图一起工作,他们将子对象传递给子视图,并使用它来查找BindableObject中该子对象的索引。这看起来非常奇怪,因此我想了解实现如此复杂的数据模型结构的其他方法。其想法是找到良好的体系结构方法,而不仅仅是像他们例子中的解决方法谢谢你发布这篇文章。我刚刚遇到了同样的问题,你也有同样令人困惑的问题。坦白说,苹果自己的教程似乎认可了一个混乱的问题,我认为他们应该感到尴尬。他们新的旗舰用户界面系统似乎只适合简单化的用户界面;这是一个有趣的限制,不能直接传递一个绑定的子对象,从而强制对其进行彻底搜索或传递索引。