2

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

  1. 在具有包装器的层次结构的顶部视图中使用声明BindableObject作为事实来源,@ObjectBinding并将其传递给具有@Binding声明的其他视图。
  2. 在具有包装器的层次结构的顶部视图中使用声明BindableObject作为事实源,使用修饰符初始化顶部视图并将其传递给其他视图或声明,或使用(在这种情况下将由 SwiftUI 自动分配,我们不需要将它传递给init)。@EnviromentObject.enviroment(BindableObject)@Binding@EnviromentObjectBindableObject

处理用户输入教程中,如果我们有BindableObject项目列表并且我们想要更改其他视图(或 RowView 甚至单独的屏幕)上的项目之一,我们需要:

  1. 使用上述任何一种方式将其传递BindableObject到更深层次的视图。
    1. 将所选项目传递到此视图。
    2. 通过在列表中BindingView查找项目来绑定项目的属性。BindableObject

一些代码可以使问题更清楚:

消息模型和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)
    }
  }
}

MessageView 表示项目列表 struct MessagesView

 : View {

    @EnvironmentObject var messageStore: MessageStore

    var body: some View {
        NavigationView {
            List(messageStore.messagesList) { message in
                NavigationButton(destination: Text(message.id)) {
                    MessageRow(message: message)
                }
            }
            .navigationBarTitle(Text("Messages"))
        }
    }
}

MessageRow 有一个 Toggle 来更新特定项目的状态 in outBindableObject

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")
       }
    }

}

这种方法显示在我上面提到的教程中。

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

4

1 回答 1

0

我认为你过于复杂了。您似乎只需要消息中的切换值。尝试这个:

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")
        }
    }
}
于 2019-06-09T15:00:54.033 回答