SwiftUI @Published和@ObservedObject不会到达NavigationLink目标

时间:2020-07-04 20:04:28

标签: class swiftui observable swiftui-navigationlink observedobject

对不起,我努力总结的标题和篇幅

我有一类@ObserableObject @Published数据,我想在通过NavigationLink访问的第二页上更改和使用新数据

class Data: ObservableObject {
     @Published var number = 5

          var correctNumber: Int {
         number + 1
     }
}

然后我有一个选择器来选择/更改号码

Picker("What times tables do you want to test your knowledge on?", selection: $data.number) {
      ForEach(0 ..< data.numberRange.count) {
         Text("\(self.data.numberRange[$0])")
      }
}

当文本在主屏幕上显示更正的数字并在更改选择器时更改/更新时,这将按预期工作

Text ("Number = \(data.correctNumber)")

然后我使用NavigationLink转到第二个屏幕

NavigationLink(destination: QuestionView()) {
    Text("Start")
}

在第二个屏幕上,设置@ObservedObject并再次显示文本。

struct QuestionView: View {
    @ObservedObject var data = Data()
        
var body: some View {
    Text("Number = \(self.data.correctNumber)")
}

按开始键时,仅显示数字5 + 1,而不显示使用选择器更改为的数字。

我已经尝试过了

  • 不使用自我。但没有明显的差异
  • 切换到绑定的$并出现以下问题;无法分配 到属性:“ correctNumber”是一个只读属性和实例 方法“ appendInterpolation”要求“ Binding”符合 '_FormatSpecifiable'
  • 将@Published添加到correctNumber,但是我无法将其添加到 计算状态

现在我没主意了,请问有人可以帮助菜鸟吗

PS,抱歉,如果术语错误,请随时纠正我,以便我下次学习。

2 个答案:

答案 0 :(得分:1)

您正在重新初始化“观察到的数据”对象,因此实际上希望该视图始终显示5 + 1。

在我看来,在给定的情况下,您实际上并不需要计算机属性,因此可以放弃它。我的建议是改为将number属性作为绑定传递,并在QuestionView中简单地将其显示为递增1。另一种方法是将计算的属性correctNumber移动到QuestionView中,但仍将number属性作为绑定传递。

这是您的情况下的情景:

  • 直接显示增加1的值
class Data: ObservableObject {
     @Published var number = 5         
}

NavigationLink(destination: QuestionView(number: $data.number)) {
    Text("Start")
}

struct QuestionView: View {
    @Binding var number : Int
        
    var body: some View {
        Text("Number = \(self.number + 1)")
    }
}
  • 并且非常相似,如果您决定仅移动计算的属性 更改QuestionView的“文本”字段以改为使用它,如下所示:
struct QuestionView: View {
    @Binding var number : Int
    
    var correctNumber: Int {
         self.number + 1
    }
        
    var body: some View {
        Text("Number = \(self.correctNumber)")
    }
}

答案 1 :(得分:1)

所有其他答案都是正确的。您需要选择最适合您的方案的

我相信您不需要@EnvironmentObject(它将对您在层次结构中的所有视图全局可用)。现在仅传递一个数字可能就足够了,但是它不能扩展(如果您想在Data中使用QuestionView的另一个属性,怎么办?)。

我建议传递Data对象,但作为 @ObservedObject

NavigationLink(destination: QuestionView(data: data)) {
    Text("Start")
}
struct QuestionView: View {
    @ObservedObject var data: Data
        
    var body: some View {
        Text("Number = \(self.data.correctNumber)")
    }
}

这样,对您的代码所做的更改将很小。而且,如果您打算仅在correctNumber中使用QuestionView,则可以按照其他答案的建议安全地将其移到那里。