在Apple的会议和教程中,我们有两个选项可将BindableObject传递给视图。
BindableObject
包装器的层次结构的顶视图中,将声明@ObjectBinding
用作真理的来源,并将其传递给声明了@Binding
的其他视图。BindableObject
包装器的层次结构顶视图中,使用声明@EnviromentObject
作为真理的来源,使用.enviroment(BindableObject)
修饰符将其初始化为顶视图,并将其传递给其他视图或使用{{ 1}}声明,或使用@Binding
(在这种情况下,@EnviromentObject
将由SwiftUI自动分配,我们不需要在init上传递它)。在Handling User Input tutorial中,如果我们有BindableObject
包含项目列表,并且我们想更改其他视图(或RowView甚至是单独的屏幕)上的项目之一,我们需要:
BindableObject
传递到更深的视图。
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
?>
答案 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")
}
}
}