I can't seem to get my "Employee View" to update based on user input in the Form inside the "ProfileFormView." Currently any input in the Form fields does not affect the "EmployeeView". I need the data that is typed into the Form to update the "Employee View." Where did I go wrong?
Here is my viewModel:
@MainActor class EmployeeViewModel: ObservableObject {
@Published var name = ""
@Published var empNum = ""
@Published var birthdate = Date(timeIntervalSince1970: 0)
@Published var dept = ""
@Published var userData: [Employee] = []
init(name: String = "", empNum: String = "", birthdate: Date = Date(timeIntervalSince1970: 0), dept: String = "", userData: [Employee] = []) {
self.name = name
self.empNum = empNum
self.birthdate = birthdate
self.dept = dept
self.userData = [
Employee(birthdate: birthdate, name: name, empNum: empNum, department: dept)]
}
}
Here is my EmployeeView:
struct EmployeeView: View {
let viewModel: EmployeeViewModel
var body: some View {
ZStack {
VStack {
List(viewModel.userData, id: \.id) { line in
EmployeeCardView(employee: line)
}
}
}
}
}
Here is my ProfileFormView:
struct ProfileFormView: View {
@EnvironmentObject var viewModel: EmployeeViewModel
@State var depts = ["HR","Management","Marketing","Development"]
var body: some View {
NavigationView {
Form {
Section(header: Text("Personal Information")) {
TextField("Name", text: $viewModel.name)
DatePicker("Birthdate", selection: $viewModel.birthdate, displayedComponents: .date)
TextField("Employee #", text: $viewModel.empNum)
Picker("Department", selection: $viewModel.dept) {
ForEach(depts, id: \.self) {
Text ($0)
}
}
}
}
}
}
}
Here is my ContentView (note that the two views are tabs under ContentView):
struct ContentView: View {
@StateObject var vm = EmployeeViewModel()
var body: some View {
NavigationView {
ZStack {
Color.gray.ignoresSafeArea()
.navigationBarHidden(true)
TabView {
ProfileFormView()
.tabItem {
Image(systemName: "square.and.pencil")
Text("Profile")
}
EmployeeView(viewModel: EmployeeViewModel())
.tabItem {
Image(systemName: "house")
Text("Home")
}
.padding()
}
.environmentObject(vm)
}
}
}
}
Here is my card view:
struct EmployeeCardView: View {
let employee: Employee
var body: some View {
ZStack{
VStack {
HStack() {
Spacer()
Text(employee.name)
.foregroundStyle(.blue)
.font(.headline)
Spacer()
Label("\(employee.birthdate.formatted(date: .abbreviated, time: .omitted))", systemImage: "calendar")
.foregroundStyle(.blue)
.font(.subheadline)
Spacer()
}
HStack() {
Spacer()
Label("\(employee.empNum)", systemImage: "person")
.foregroundStyle(.blue)
.font(.subheadline)
Spacer()
Label("\(employee.department)", systemImage: "building")
.foregroundStyle(.blue)
.font(.subheadline)
Spacer()
}
}
}
}
}
Here is my data model:
struct Employee: Codable, Identifiable {
var id = UUID()
var birthdate = Date(timeIntervalSince1970: 0)
var name = ""
var empNum = "8675309"
var department = ""
init(id: UUID = UUID(), birthdate: Date = Date(timeIntervalSince1970: 0), name: String = "", empNum: String = "8675309", department: String = "") {
self.id = id
self.birthdate = birthdate
self.name = name
self.empNum = empNum
self.department = department
}
}
struct MockData {
static let mockData = [sampleUser,sampleUser, sampleUser]
static let sampleUser = Employee(birthdate: Date(timeIntervalSince1970: 0), name: "Bob", empNum: "8675309", department: "HR")
}
Here is a screenshot of the card view with mock data: