Reputation: 310
@EnvironmentObject var v: Variables
if !isActiveView {
VStack {
}
.onReceive(v.$AllAirplanes) { plane in
if plane != [] {
DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
withAnimation(Animation.easeOut(duration: 1.0)) {
isAnimation.toggle()
}
}
DispatchQueue.main.asyncAfter(deadline: .now() + 3.8) {
withAnimation {
isActiveView.toggle()
locationViewModel.getUserLocation()
}
}
}
}
}
This is my code. I am getting v.$AllAirplanes from firebase and trying to get my loading screen to keep going until the variable does not equal []. The problem is that it only tests once, so I'm forever stuck on the loading screen, even if the value changes.
From what I've read, I thought OnReceive was how, and the best way to do this. Should I go about this another way?
Edit: I'm updating v.AllAirplanes with this function -
@StateObject var v = Variables()
func getAllAirplanes() {
db.collection("Airplanes")
.addSnapshotListener { querySnapshot, error in
guard (querySnapshot?.documents) != nil else {
print("Error fetching documents: \(error!)")
return
}
v.AllAirplanes.removeAll()
for document in querySnapshot!.documents {
print("\(document.documentID) => \(document.data())")
//GET DATA AND SET TO VARIABLE
v.AllAirplanes.append(document.documentID)
}
v.AllAirplanes.remove(object: "Simulator")
//v.AllAirplanes.append("-Please select an airplane-")
print(
"""
------------------------------
All Airplanes: \(v.AllAirplanes)
------------------------------
"""
)
}
}
and this is my class -
class Variables: ObservableObject {
@Published var AllAirplanes: String<Array> = []
}
Upvotes: 1
Views: 331
Reputation: 36368
Here is my test example code that shows .onRecieve
working as expected.
class Variables: ObservableObject {
@Published var AllAirplanes: [String] = ["1","2","3"]
}
struct TestingView: View {
@EnvironmentObject var v: Variables
@State var isActiveView = false
@State var isAnimation = false
var body: some View {
// for testing, wait 2 secs then click the button
Button(action: {
// change AllAirplanes
v.AllAirplanes.append(UUID().uuidString)
isActiveView.toggle()
}) {
Text("Test change AllAirplanes (wait 2 seconds first)")
}
if !isActiveView {
VStack {
Text("TestingView")
}
.onReceive(v.$AllAirplanes) { plane in
print("-----> in onReceive plane: \(plane)")
if plane != [] {
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
withAnimation(Animation.easeOut(duration: 1.0)) {
isAnimation.toggle()
}
}
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
withAnimation {
isActiveView.toggle()
// locationViewModel.getUserLocation()
}
}
}
}
}
}
}
struct ContentView: View {
@StateObject var v = Variables()
var body: some View {
TestingView().environmentObject(v)
}
}
Upvotes: 2