SwiftUI - Using 'ObservableObject' and @En

2019-08-21 11:27发布

问题:

I would like to conditionally display different views in my application - if a certain boolean is true, one view will be displayed. If it is false, a different view will be displayed. This boolean is within an ObservableObject class, and is changed from one of the views that will be displayed.

PracticeStatus.swift (the parent view)

import Foundation
import SwiftUI
import Combine

class PracticeStatus: ObservableObject  {
    @Published var showResults:Bool = false
}

PracticeView.swift (the parent view)

struct PracticeView: View {
    @EnvironmentObject var practiceStatus: PracticeStatus

    var body: some View {
        VStack {
            if practiceStatus.showResults {
                ResultView()
            } else {
                QuestionView().environmentObject(PracticeStatus())
            }
        }
    }
}

QuestionView.swift

struct QuestionView: View {
    @EnvironmentObject var practiceStatus: PracticeStatus

    var body: some View {
        VStack {
            ...
            Button(action: {
                self.practiceStatus.showResults = true
            }) { ... }
            ...
        }
    }
}

However, this code doesn't work. When the button within QuestionView is pressed, ResultView is not displayed. Does anybody have a solution? Thanks!

回答1:

Have you tried to compile your code? There are several basic errors:

  1. Variable practice does not exist in PracticeView. Did you mean practiceStatus?
  2. Variable userData does not exist in QuestionView. Did you mean practiceStatus?
  3. You are calling PracticeView from inside PracticeView! You'll definetely get a stack overflow ;-) Didn't you mean QuestionView?

Below is a working code:

import Foundation
import SwiftUI
import Combine

class PracticeStatus: ObservableObject  {
    @Published var showResults:Bool = false
}

struct ContentView: View {
    @State private var flag = false

    var body: some View {
        PracticeView().environmentObject(PracticeStatus())
    }
}

struct PracticeView: View {
    @EnvironmentObject var practiceStatus: PracticeStatus

    var body: some View {
        VStack {
            if practiceStatus.showResults {
                ResultView()
            } else {
                QuestionView()
            }
        }
    }
}

struct QuestionView: View {
    @EnvironmentObject var practiceStatus: PracticeStatus

    var body: some View {
        VStack {

            Button(action: {
                self.practiceStatus.showResults = true
            }) {
                Text("button")
            }
        }
    }
}

struct ResultView: View {
    @State private var flag = false

    var body: some View {
        Text("RESULTS")
    }
}