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]()
}