簡體   English   中英

Swift 5:ObservedObject 未更新

[英]Swift 5: ObservedObject Not updating

我創建了一個名為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 的共享狀態沒有在“觀察”它的所有視圖中更新。 同樣是 swift 的新手,如果我沒有包含回答我不知道的問題所需的任何信息,我深表歉意。

目前尚不清楚,您如何一起使用這些視圖,例如,對於其他人來說,添加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())
    }
}

你將實現這一目標: 在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM