【发布时间】:2019-12-24 08:20:30
【问题描述】:
我试图理解为什么传递 @ObservedObject 变量不适用于嵌套子视图。可以传递数据,但更改仅反映在创建 @ObservedObject 变量的根视图中。更改不会显示在子视图中。查看 Apple 文档(已针对 Xcode beta 5 进行了更新),答案似乎是创建环境对象和常规变量,以便从环境对象中获取正确的索引。这里是苹果example。
我的理解是@ObservedObject 可用于从多个视图引用变量,但如果您希望可以从任何视图访问数据,那么您应该使用环境对象。因此,我相信通过@ObservedObject 应该是可能的。我认为正在发生的问题是,由于 ScreenTwo 正在将 @Binding 变量传递给 DetailsView,这就是导致问题的原因。为了解决这个问题,我认为你需要继续传递完整的@ObservedObject,但是你需要某种类型的常规变量来获得正确的索引。
我觉得所有这些都应该更直接。
import SwiftUI
import Combine
struct Sport: Identifiable{
var id = UUID()
var name : String
var isFavorite = false
var school : String
}
final class SportData: ObservableObject {
@Published var store =
[
Sport(name: "soccer", isFavorite: false, school: "WPI"),
Sport(name: "tennis", isFavorite: false, school: "WPI"),
Sport(name: "swimming", isFavorite: true, school: "WPI"),
Sport(name: "running", isFavorite: true, school: "RIT"),
]
}
struct Testing: View {
@ObservedObject var sports = SportData()
var body: some View {
NavigationView{
List{
ForEach($sports.store){ sport in
NavigationLink(destination: ScreenTwo(sport: sport)){
HStack {
Text(sport.value.name)
Spacer()
Text(sport.value.isFavorite.description)
}
}
}
}
}.navigationBarTitle("Settings")
}
}
struct ScreenTwo : View{
@Binding var sport : Sport
var body: some View{
NavigationLink(destination: DetailsView(sport: $sport)){
Text(sport.isFavorite.description)
}
}
}
struct DetailsView: View {
@Binding var sport : Sport
var body: some View {
Button(action: {
self.sport.isFavorite.toggle()
self.sport.name = "Ricky"
}) {
Text(sport.isFavorite.description)
Text(sport.name)
}
}
}
#if DEBUG
struct Testing_Previews: PreviewProvider {
static var previews: some View {
Testing()
}
}
#endif
【问题讨论】:
-
这里似乎工作正常。首先选择 Ricky,然后通过单击 false 选择第二个
NavigationLink,然后它会显示一个按钮,该按钮会立即更改除了 Ricky 之外的false和一旦按下右侧的 false。还是第二个NavigationLink不需要? -
我不确定我是否遵循您的逻辑。以下是当前发生的情况: 1. 按第一行的“足球” 2. 单击导航链接 3. 单击“假足球”按钮。 4. 一直到根视图,第一行将是“Ricky true”。应该发生的是,在第 3 步,按钮应立即更改为“Ricky true”,然后当您返回第二个屏幕时,它应该显示“true”。根屏幕应显示“Ricky true”。
-
啊,现在我明白你的意思了。是的,这看起来很奇怪。好像 SwiftUI 不想重绘
destination:中的内容。尽管我之前说过,它不会改变destination:,只有重绘才能做到这一点。 -
没错。它没有产生预期的行为。这是一个错误,还是一些我不明白的更深层次的逻辑我不确定。
-
我也注意到了。但是,不要认为这是因为 NavigationLink。我认为这更多地与 ObservedObject 是变量的真实来源这一事实有关,而 Binding 只是对它的引用。因此,当 ScreenTwo 将 Binding 传递给另一个 Binding 时,我认为这会导致问题。在我所做的所有阅读和我看过的示例中,没有人像这样传递变量。它们只将 ObservedObject 传递给单个 Binding。该绑定永远不会传递给其他任何东西。这让我很困惑,因为这似乎是 ObservedObject 的重点。
标签: xcode nested observable swiftui