Home > Net >  creating an Environment object
creating an Environment object

Time:03-13

can someone please help me with this. Whenever I am trying to declare gp as an Environment object, the list disappears. The list works fine when the gp is a @State variable. Could you please help me with creating gp as a global variable so that it works in another screen of Final. I want to call gp in the Final screen so that I can use the value of gp to calculate something else.

import SwiftUI
    
    
    struct Calculation: View {
        
        @State var load1 = Float()
        @State var load2 = Float()
        //@State var gp : Float = 0
        @State var rate: Float = 0
        @ObservedObject var taskStore = TaskStore()
        @EnvironmentObject var userSettings: UserSettings
        func addNewToDo() {
            taskStore.tasks.append(Task(id: String(taskStore.tasks.count   1), toDoItem: " Earning: =  \(rate.description)", amount: rate))
        }
        
        var body: some View {
            NavigationView {
                VStack {
                    List {
                        
                        Section(header:Text("load 2"))
                        {
                            TextField("Enter value of load 1", value: $load1, format: .number)
                            TextField("Enter value of load 1", value: $load2, format: .number)
                        }
                        
                        HStack {
                            Button(String(format: "Add Load"), action: {
                                print("pay for the shift is ")
                                print(Rocky(mypay: rate))
                                userSettings.gp  = rate
                            })
                            
                            Button(action: {
                                addNewToDo()
                                Rocky(mypay: rate)
                            },
                            label: {
                                Text(" ")
                            })
                        }
                        
                        ForEach(self.taskStore.tasks) { task in
                            Text(task.toDoItem)
                        }
                        .onMove(perform : self.move)
                        .onDelete(perform : self.delete) //For each
                        
                    }
                    .navigationBarTitle("SHIFTS")
                    .navigationBarItems(trailing: EditButton()) //List
                    
                    Text("Gross Pay = $\(userSettings.gp) ")
                     NavigationLink(destination: Final(), label: {Text("Next")})
                }.onAppear()
                
            }
        }
        
        func Rocky(mypay: Float)
        {
            rate = load1   load2
            print("Sus \(userSettings.gp)")
        }
        func move(from source : IndexSet, to destination : Int)
        {
            taskStore.tasks.move(fromOffsets: source, toOffset: destination)
        }
        func delete(at offsets : IndexSet) {
            if let index = offsets.first {  //<-- Here
                let task = taskStore.tasks[index]
                userSettings.gp -= task.amount
            }
            taskStore.tasks.remove(atOffsets: offsets)
        }
    }
    
    struct Final: View {
        @EnvironmentObject var userSettings: UserSettings
        var body: some View {
            Text("Final result \(userSettings.gp)")
        }
    }

Another part of the file is as below:

import Foundation
import SwiftUI
import Combine
class UserSettings: ObservableObject
{
@Published var gp : Float = 0
    
}

struct Task : Identifiable {
    var id = String()
    var toDoItem = String()
    var amount : Float = 0 //<-- Here
}

class TaskStore : ObservableObject {
    @Published var tasks = [Task]()
}

CodePudding user response:

To use your UserSettings ObservableObject, you need to declare it before you call the Calculation view. Pass it to Calculation using .environmentObject(userSettings) so that it is available in Calculation and all "sub views" (like Final), such as in this example code:

struct ContentView: View {
    @StateObject var userSettings = UserSettings()   // <-- here
    
    var body: some View {
        Calculation().environmentObject(userSettings)  // <-- here
    }
}

EDIT-1: here is the full test code I used:

import SwiftUI

@main
struct TestApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}


struct ContentView: View {
    @StateObject var userSettings = UserSettings()   // <-- here
    
    var body: some View {
        Calculation().environmentObject(userSettings)  // <-- here
    }
}

struct Calculation: View {
    
    @State var load1 = Float()
    @State var load2 = Float()
    @State var rate: Float = 0
    @StateObject var taskStore = TaskStore()  // <-- here
    
    @EnvironmentObject var userSettings: UserSettings
    
    func addNewToDo() {
        taskStore.tasks.append(Task(id: String(taskStore.tasks.count   1), toDoItem: " Earning: =  \(rate.description)", amount: rate))
    }
    
    var body: some View {
        NavigationView {
            VStack {
                List {
                    Section(header:Text("load 2")){
                        TextField("Enter value of load 1", value: $load1, format: .number)
                        TextField("Enter value of load 1", value: $load2, format: .number)
                    }
                    
                    HStack {
                        Button(String(format: "Add Load"), action: {
                            print("pay for the shift is ")
                            print(Rocky(mypay: rate))
                            userSettings.gp  = rate
                        })
                        
                        Button(action: {
                            addNewToDo()
                            Rocky(mypay: rate)
                        },
                               label: {
                            Text(" ")
                        })
                    }
                    
                    ForEach(self.taskStore.tasks) { task in
                        Text(task.toDoItem)
                    }
                    .onMove(perform : self.move)
                    .onDelete(perform : self.delete) //For each
                    
                }
                .navigationBarTitle("SHIFTS")
                .navigationBarItems(trailing: EditButton()) //List
                
                Text("Gross Pay = $\(userSettings.gp) ")
                NavigationLink(destination: Final(), label: {Text("Next")})
            }.onAppear()
            
        }
    }
    
    func Rocky(mypay: Float){
        rate = load1   load2
        print("Sus \(userSettings.gp)")
    }
    
    func move(from source : IndexSet, to destination : Int){
        taskStore.tasks.move(fromOffsets: source, toOffset: destination)
    }
    
    func delete(at offsets : IndexSet) {
        if let index = offsets.first {  //<-- Here
            let task = taskStore.tasks[index]
            userSettings.gp -= task.amount
        }
        taskStore.tasks.remove(atOffsets: offsets)
    }
}

struct Final: View {
    @EnvironmentObject var userSettings: UserSettings
    var body: some View {
        Text("Final result \(userSettings.gp)")
    }
}


class UserSettings: ObservableObject {
    @Published var gp : Float = 0
}

struct Task : Identifiable {
    var id = String()
    var toDoItem = String()
    var amount : Float = 0 //<-- Here
}

class TaskStore : ObservableObject {
    @Published var tasks = [Task]()
}
  • Related