将BindableObject传递给视图

时间:2019-06-09 13:29:37

标签: ios swiftui swift5.1

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

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

Handling User Input tutorial中,如果我们有BindableObject包含项目列表,并且我们想更改其他视图(或RowView甚至是单独的屏幕)上的项目之一,我们需要:

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

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

消息模型和BindableObject

BindableObject

代表项目列表的MessageView struct MessagesView

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

MessageRow,其中有一个Toggle可以更新出 : 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")) } } } 内特定项目的状态

BindableObject

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

问题: 我想将Message作为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

1 个答案:

答案 0 :(得分: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")
        }
    }
}