简体   繁体   English

Swift 5:ObservedObject 未更新

[英]Swift 5: ObservedObject Not updating

I've created an ObservableObject class called ActiveQuiz with info I want to share across multiple views:我创建了一个名为ActiveQuiz的 ObservableObject 类,其中包含我想在多个视图中共享的信息:

import Foundation

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

In one of the views I display text, that if tapped on will increase the iterator which in turn updates the text as it has moved on to the next entry in the questions array:在我显示文本的一个视图中,如果点击它会增加迭代器,迭代器会随着文本移动到问题数组中的下一个条目而更新文本:

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
            } )
    }
}

In the other view I have a count which displays where the iterator is:在另一个视图中,我有一个计数,显示迭代器的位置:

import SwiftUI

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

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

The text from the first view is updating as expected but the iterator from the second view stays at the initial 1/x.第一个视图中的文本正在按预期更新,但第二个视图中的迭代器保持在最初的 1/x。

Question : Being new the Swift, I don't understand why the shared state of the ObservableObject ActiveQuiz isn't updating across all view that are "observing" it.问题:作为 Swift 新手,我不明白为什么ObservableObject ActiveQuiz 的共享状态没有在“观察”它的所有视图中更新。 Also in being new to swift, I apologize if I've not included any info needed to answer the question that I'm not aware of.同样是 swift 的新手,如果我没有包含回答我不知道的问题所需的任何信息,我深表歉意。

It's not clear, how you use these views together, maybe for others it will be helpful to add ContentView , for example.目前尚不清楚,您如何一起使用这些视图,例如,对于其他人来说,添加ContentView可能会有所帮助。 As I see, you use 2 different ActiveQuiz instances.如我所见,您使用了 2 个不同的ActiveQuiz实例。 So your Question struct have 1 instance and you update it's iterator and QuestionCounter has it's own instance, which is not updating from the first one.所以你的Question结构有 1 个实例,你更新它的迭代器,而QuestionCounter有它自己的实例,它不是从第一个更新的。 I think the solution should be to use @EnvironmentObject for both structs, like this (I simplified your example because of lack of code):我认为解决方案应该是对两个结构都使用@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())
    }
}

and you will achieve this:你将实现这一目标: 在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM