在 Apple 的会话和教程中,我们有两个选项可以将 BindableObject 传递给视图。
- 在具有包装器的层次结构的顶部视图中使用声明
BindableObject
作为事实来源,@ObjectBinding
并将其传递给具有@Binding
声明的其他视图。 - 在具有包装器的层次结构的顶部视图中使用声明
BindableObject
作为事实源,使用修饰符初始化顶部视图并将其传递给其他视图或声明,或使用(在这种情况下将由 SwiftUI 自动分配,我们不需要将它传递给init)。@EnviromentObject
.enviroment(BindableObject)
@Binding
@EnviromentObject
BindableObject
从处理用户输入教程中,如果我们有BindableObject
项目列表并且我们想要更改其他视图(或 RowView 甚至单独的屏幕)上的项目之一,我们需要:
- 使用上述任何一种方式将其传递
BindableObject
到更深层次的视图。- 将所选项目传递到此视图。
- 通过在列表中
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
?