Ios 将BindableObject传递给视图
在Apple的会话和教程中,我们有两个选项可以将BindableObject传递给视图Ios 将BindableObject传递给视图,ios,swiftui,swift5.1,Ios,Swiftui,Swift5.1,在Apple的会话和教程中,我们有两个选项可以将BindableObject传递给视图 使用declareBindableObject作为层次结构中带有@ObjectBinding包装器的顶层视图中的真理源,并将其传递给声明了@Binding的其他视图 在带有@environmentobject包装器的层次结构的顶部视图中,使用declareBindableObject作为真理的来源,使用.environment(BindableObject)修饰符初始化顶部视图,并将其传递给其他视图或声明了@
BindableObject
作为层次结构中带有@ObjectBinding
包装器的顶层视图中的真理源,并将其传递给声明了@Binding
的其他视图@environmentobject
包装器的层次结构的顶部视图中,使用declareBindableObject
作为真理的来源,使用.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中该子对象的索引。这看起来非常奇怪,因此我想了解实现如此复杂的数据模型结构的其他方法。其想法是找到良好的体系结构方法,而不仅仅是像他们例子中的解决方法谢谢你发布这篇文章。我刚刚遇到了同样的问题,你也有同样令人困惑的问题。坦白说,苹果自己的教程似乎认可了一个混乱的问题,我认为他们应该感到尴尬。他们新的旗舰用户界面系统似乎只适合简单化的用户界面;这是一个有趣的限制,不能直接传递一个绑定的子对象,从而强制对其进行彻底搜索或传递索引。