Swift 5:ObservedObject无法更新

时间:2020-02-27 03:07:45

标签: swift swiftui

我创建了一个名为ActiveQuiz的ObservableObject类,其中包含我想在多个视图之间共享的信息:

import Foundation

class ActiveQuiz: ObservableObject{
    @Published var iterator = 0
    @Published var questions = createQuiz()
}

在其中一个视图中,我显示文本,如果点按该文本,则会增加迭代器,迭代器又会在文本移至问题数组中的下一个条目时更新文本:

import SwiftUI

struct Question: View {
    @ObservedObject var activeQuiz = ActiveQuiz()

    var body: some View {
        Text(self.activeQuiz.questions[self.activeQuiz.iterator].countryInfo.capital)
            .font(.title)
            .onTapGesture(perform: {
                // increase iterator by 1 unless it's at the end, then put back to 0
                self.activeQuiz.iterator = self.activeQuiz.iterator + 1 == self.activeQuiz.questions.count ? 0 : self.activeQuiz.iterator + 1
            } )
    }
}

在另一个视图中,我有一个计数,用于显示迭代器的位置:

import SwiftUI

struct QuestionCounter: View {
    @ObservedObject var activeQuiz = ActiveQuiz()

    var body: some View {
        Text(String(self.activeQuiz.iterator + 1) + "/" + String(self.activeQuiz.questions.count))
    }
}

第一个视图中的文本正在按预期方式更新,但第二个视图中的迭代器保持在初始1 / x。

问题:作为Swift的新成员,我不明白为什么ObservableObject ActiveQuiz的共享状态没有在“观察”它的所有视图中更新。同样,对于新手来说,如果我还没有提供回答我所不知道的问题所需的任何信息,我深表歉意。

1 个答案:

答案 0 :(得分:0)

目前尚不清楚如何将这些视图一起使用,例如,对于其他人来说,添加ContentView会有所帮助。如我所见,您使用2个不同的ActiveQuiz实例。因此,您的Question结构有1个实例,您将其更新为迭代器,而QuestionCounter具有其自己的实例,该实例不会从第一个实例进行更新。我认为解决方案应该是对两个结构都使用@EnvironmentObject,就像这样(由于缺少代码,我简化了您的示例):

import SwiftUI
import Combine

class ActiveQuiz: ObservableObject {
    @Published var iterator = 0
}

struct UsingEnvironmentObject: View {

    @EnvironmentObject var activeQuiz: ActiveQuiz
    var body: some View {
        VStack {

            Question() // it will take EnvironmentObject from parent
            QuestionCounter() // this one will take the same EnvironmentObject from parent

        }
    }
}

// more representative solution
struct UsingEnvironmentObject: View {

    @ObservedObject var activeQuiz = ActiveQuiz()

    var body: some View {
        VStack {
            // here you see, that both structs use one instance
            Question()
                .environmentObject(activeQuiz)
            QuestionCounter()
                .environmentObject(activeQuiz)

        }
    }
}

struct Question: View {

    @EnvironmentObject var activeQuiz: ActiveQuiz

    var body: some View {
        Text("some text from question")
            .font(.title)
            .onTapGesture(perform: {
                // increase iterator by 1 unless it's at the end, then put back to 0
                self.activeQuiz.iterator = self.activeQuiz.iterator + 1 == 10 ? 0 : self.activeQuiz.iterator + 1
            } )
    }
}

struct QuestionCounter: View {
    @EnvironmentObject var activeQuiz: ActiveQuiz

    var body: some View {
        Text(String(self.activeQuiz.iterator + 1) + "/10")
    }
}



struct UsingEnvironmentObject_Previews: PreviewProvider {
    static var previews: some View {
        UsingEnvironmentObject()
        .environmentObject(ActiveQuiz())
    }
}

,您将实现以下目标: enter image description here