【问题标题】:SwiftUI @Published and @ObservedObject not going to NavigationLink destinationSwiftUI @Published 和 @ObservedObject 不会去 NavigationLink 目的地
【发布时间】:2020-07-04 20:04:28
【问题描述】:

抱歉标题和长度让我难以总结

我有一类@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,而不是使用选择器更改为的数字。

我试过了;

  • 不使用自我。但没有明显区别
  • 交换到绑定 $ 并遇到以下问题;无法分配 to property: 'correctNumber' 是一个 get-only 属性和 Instance 方法 'appendInterpolation' 要求 'Binding' 符合 '_FormatSpecifiable'
  • 将 @Published 添加到 correctNumber 但我无法将其添加到 计算状态

现在我没有想法了,任何人都可以帮助一个菜鸟,拜托

PS 如果术语有误,请见谅,欢迎指正,以便下次学习

【问题讨论】:

    标签: class swiftui observable swiftui-navigationlink observedobject


    【解决方案1】:

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

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

    我建议传递 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)")
        }
    }
    

    这样对您的代码所做的更改将是最小的。如果您打算仅在 QuestionView 中使用 correctNumber - 您可以安全地将其移到那里*如另一个答案中的建议)。

    【讨论】:

      【解决方案2】:

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

      在我看来,在给定的情况下,您实际上并不需要计算机属性,因此您可以放弃它。我的建议是将 number 属性作为绑定传递,并在 QuestionView 中简单地将其显示为 1。另一种方法是在 QuestionView 中移动计算属性 correctNumber 但仍将 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 的 Text 字段以使用它,如下所示:
      struct QuestionView: View {
          @Binding var number : Int
          
          var correctNumber: Int {
               self.number + 1
          }
              
          var body: some View {
              Text("Number = \(self.correctNumber)")
          }
      }
      

      【讨论】:

      • 从问题中的示例代码来看,只需将一个数字传递给 QuestionView 就足够了。但是,当您决定在此视图中使用 Data 的另一个属性时,这不允许任何灵活性。将Data 对象传递给QuestionView 可能会更好。我同意其余的。
      • 谢谢@bde.dev 这是一个很好的答案,特别是因为它解释了我的代码为什么会这样。
      猜你喜欢
      • 2020-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多