Swift 5: ObservedObject Не обновляется - PullRequest
0 голосов
/ 27 февраля 2020

Я создал класс ObservableObject с именем ActiveQuiz с информацией, которую я хочу передать нескольким представлениям:

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, я прошу прощения, если я не включил какую-либо информацию, необходимую для ответа на вопрос, о котором я не знаю.

1 Ответ

1 голос
/ 27 февраля 2020

Непонятно, как вы используете эти виды вместе, может быть, для других было бы полезно добавить, например, 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...