Skip to main content
AI Assist is now on Stack Overflow. Start a chat to get instant answers from across the network. Sign up to save and share your chats.
deleted 1132 characters in body
Source Link
David
  • 57
  • 8

I have successfully displayed the data to the UI, but I want the user to be able to update my data again when tapping the "Save" button . Hope you can help me!

Profile

struct Profile: View { @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode> @ObservedObject var profileViewModel: ProfileViewModel @State var profileItem: [String] = [] @State var profileEditorRow: [ProfileEditorItem] = [] var body: some View { VStack { ForEach(profileEditorRow) { i in ProfileEditorRow(i: editor) } } Button("Save") { profileViewModel.updateData()  }   } 

ProfileRow

struct ProfileRow: View { @State var editor: ProfileEditorItem var body: some View { ZStack(alignment: .bottom) { HStack(alignment: .center) { Text(editor.label) VStack(alignment: .center) { I have successfully displayed the data to the TextField(""UI,text: $editor.item) } }  but I want the user to } be able to update my data again when tapping the "Save" button .padding(.leading, 15)  Hope you can help }me! } 

I have successfully displayed the data to the UI, but I want the user to be able to update my data again when tapping the "Save" button . Hope you can help me!

I have successfully displayed the data to the UI, but I want the user to be able to update my data again when tapping the "Save" button . Hope you can help me!

Profile

struct Profile: View { @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode> @ObservedObject var profileViewModel: ProfileViewModel @State var profileItem: [String] = [] @State var profileEditorRow: [ProfileEditorItem] = [] var body: some View { VStack { ForEach(profileEditorRow) { i in ProfileEditorRow(i: editor) } } Button("Save") { profileViewModel.updateData()  }   } 

ProfileRow

struct ProfileRow: View { @State var editor: ProfileEditorItem var body: some View { ZStack(alignment: .bottom) { HStack(alignment: .center) { Text(editor.label) VStack(alignment: .center) {  TextField("",text: $editor.item) } }  }  .padding(.leading, 15)  } } 

I have successfully displayed the data to the UI, but I want the user to be able to update my data again when tapping the "Save" button . Hope you can help me!

I have successfully displayed the data to the UI, but I want the user to be able to update my data again when tapping the "Save" button . Hope you can help me!

Profile

 I have successfully displayed the data to the UI, but I want the user to be able to update my data again when tapping the "Save" button . Hope you can help me! 
deleted 1343 characters in body; deleted 887 characters in body
Source Link
David
  • 57
  • 8

ProfileHost

struct ProfileHost: View { @State private var editMode: EditMode = .inactive @ObservedObject var viewModel = ProfileViewModel() @EnvironmentObject var user: LoginViewModel @State private var showingOptions = false var profileLabel: [String] = ["Edit account", "Change password", "Favourites", "Notification", "Role", "Contact us"] var profileImageName: [String] = ["profile_account", "profile_password", "profile_fav", "profile_noti", "profile_role", "profile_contact"] var profileSetting: [ProfileSetting] { var result: [ProfileSetting] = [] for n in 1...6 { result.append(ProfileSetting(id: n, imageName: profileImageName[n-1], labelName: profileLabel[n-1])) } return result } var body: some View { NavigationView { List { ForEach(profileSetting) { profile in switch profile.id { case 1: NavigationLink(destination: ProfileEditor(profileViewModel: viewModel)) { ProfileRow(profileSetting: profile) } .onAppear { viewModel.fetchData(userId: user.session?.uid) } } } 

ProfileEditorProfile

struct ProfileEditorProfile: View { @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode> @ObservedObject var profileViewModel: ProfileViewModel   @EnvironmentObject var loginViewModel : LoginViewModel  @State var profileItem: [String] = [] @State var profileEditorRow: [ProfileEditorItem] = [] var body: some View { VStack { ForEach(profileEditorRow) { editori in // show last line on the last row if editor.id == 5 { ProfileEditorRow(editor: editor, showLastLine: true) } else { ProfileEditorRow(editori: editor, showLastLine: false) } .onAppear() { profileItem = [profileViewModel.user.name, profileViewModel.user.birthDay, profileViewModel.user.gender, profileViewModel.user.role.first ?? "", profileViewModel.user.birthDay] for n in 1...5 { profileEditorRow.append(ProfileEditorItem(id: n, label: profileLabel[n-1], item: profileItem[n-1])) }   }  }   } Button("Save") { profileViewModel.updateData(userId: loginViewModel.session?.uid) } } 

ProfileEditorRowProfileRow

struct ProfileEditorRowProfileRow: View { @State var editor: ProfileEditorItem var body: some View { ZStack(alignment: .bottom) { HStack(alignment: .center) { Text(editor.label) .fontWeight(.none) .font(.custom("Poppins-Regular", size: 16))   .frame(maxWidth: 70, alignment: .leading)   .padding(.trailing, 20)  .padding(.top,-10) VStack(alignment: .center) { TextField("",text: $editor.item) .poppinsRegularFont(size: 16) .foregroundColor(ColorManager.textGray)   .frame(maxHeight:40)  } Rectangle().fill(ColorManager.lineGray) .frame(height: 1, alignment: .bottom) .frame(maxWidth: .infinity) } } .padding(.leading, 15) } } 

ProfileHost

struct ProfileHost: View { @State private var editMode: EditMode = .inactive @ObservedObject var viewModel = ProfileViewModel() @EnvironmentObject var user: LoginViewModel @State private var showingOptions = false var profileLabel: [String] = ["Edit account", "Change password", "Favourites", "Notification", "Role", "Contact us"] var profileImageName: [String] = ["profile_account", "profile_password", "profile_fav", "profile_noti", "profile_role", "profile_contact"] var profileSetting: [ProfileSetting] { var result: [ProfileSetting] = [] for n in 1...6 { result.append(ProfileSetting(id: n, imageName: profileImageName[n-1], labelName: profileLabel[n-1])) } return result } var body: some View { NavigationView { List { ForEach(profileSetting) { profile in switch profile.id { case 1: NavigationLink(destination: ProfileEditor(profileViewModel: viewModel)) { ProfileRow(profileSetting: profile) } .onAppear { viewModel.fetchData(userId: user.session?.uid) } } } 

ProfileEditor

struct ProfileEditor: View { @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode> @ObservedObject var profileViewModel: ProfileViewModel   @EnvironmentObject var loginViewModel : LoginViewModel  @State var profileItem: [String] = [] @State var profileEditorRow: [ProfileEditorItem] = [] var body: some View { VStack { ForEach(profileEditorRow) { editor in // show last line on the last row if editor.id == 5 { ProfileEditorRow(editor: editor, showLastLine: true) } else { ProfileEditorRow(editor: editor, showLastLine: false) } .onAppear() { profileItem = [profileViewModel.user.name, profileViewModel.user.birthDay, profileViewModel.user.gender, profileViewModel.user.role.first ?? "", profileViewModel.user.birthDay] for n in 1...5 { profileEditorRow.append(ProfileEditorItem(id: n, label: profileLabel[n-1], item: profileItem[n-1])) }   }  }   } Button("Save") { profileViewModel.updateData(userId: loginViewModel.session?.uid) } } 

ProfileEditorRow

struct ProfileEditorRow: View { @State var editor: ProfileEditorItem var body: some View { ZStack(alignment: .bottom) { HStack(alignment: .center) { Text(editor.label) .fontWeight(.none) .font(.custom("Poppins-Regular", size: 16))   .frame(maxWidth: 70, alignment: .leading)   .padding(.trailing, 20)  .padding(.top,-10) VStack(alignment: .center) { TextField("",text: $editor.item) .poppinsRegularFont(size: 16) .foregroundColor(ColorManager.textGray)   .frame(maxHeight:40)  } Rectangle().fill(ColorManager.lineGray) .frame(height: 1, alignment: .bottom) .frame(maxWidth: .infinity) } } .padding(.leading, 15) } } 

Profile

struct Profile: View { @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode> @ObservedObject var profileViewModel: ProfileViewModel @State var profileItem: [String] = [] @State var profileEditorRow: [ProfileEditorItem] = [] var body: some View { VStack { ForEach(profileEditorRow) { i in ProfileEditorRow(i: editor) } } Button("Save") { profileViewModel.updateData() } } 

ProfileRow

struct ProfileRow: View { @State var editor: ProfileEditorItem var body: some View { ZStack(alignment: .bottom) { HStack(alignment: .center) { Text(editor.label) VStack(alignment: .center) { TextField("",text: $editor.item) } } } .padding(.leading, 15) } } 
deleted 234 characters in body
Source Link
David
  • 57
  • 8

Design enter image description here

Database

enter image description here

Fetch data

class ProfileViewModel: ObservableObject { @Published var user = Profile(id: "", image: "", birthDay: "", role: [], gender: "", name: "") private var ref: DatabaseReference = Database.database().reference() func fetchData(userId: String? = nil) { // 8hOqqnFlfGZTj1u5tCkTdxAED2I3 ref.child("users").child(userId ?? "default").observe(.value) { [weak self] (snapshot) in guard let self = self, let value = snapshot.value else { return } do { print("user: \(value)") self.user = try FirebaseDecoder().decode(Profile.self, from: value) } catch let error { print(error) } } func updateData(userId: String? = nil) { guard let key = ref.child(userId ?? "default").childByAutoId().key else { return } let post = [user] let childUpdates = ["/posts/\(key)": post, "/user-posts/\(String(describing: userId))/\(key)/": post] ref.updateChildValues(childUpdates) } } } struct Profile: Decodable, Identifiable { let id: String let image: String var birthDay: String var role: [String] var gender: String var name: String } 

Error

Design enter image description here

Database

enter image description here

Fetch data

class ProfileViewModel: ObservableObject { @Published var user = Profile(id: "", image: "", birthDay: "", role: [], gender: "", name: "") private var ref: DatabaseReference = Database.database().reference() func fetchData(userId: String? = nil) { // 8hOqqnFlfGZTj1u5tCkTdxAED2I3 ref.child("users").child(userId ?? "default").observe(.value) { [weak self] (snapshot) in guard let self = self, let value = snapshot.value else { return } do { print("user: \(value)") self.user = try FirebaseDecoder().decode(Profile.self, from: value) } catch let error { print(error) } } func updateData(userId: String? = nil) { guard let key = ref.child(userId ?? "default").childByAutoId().key else { return } let post = [user] let childUpdates = ["/posts/\(key)": post, "/user-posts/\(String(describing: userId))/\(key)/": post] ref.updateChildValues(childUpdates) } } } struct Profile: Decodable, Identifiable { let id: String let image: String var birthDay: String var role: [String] var gender: String var name: String } 

Error

added 260 characters in body; deleted 7 characters in body
Source Link
David
  • 57
  • 8
Loading
added 357 characters in body
Source Link
David
  • 57
  • 8
Loading
added 832 characters in body
Source Link
David
  • 57
  • 8
Loading
added 832 characters in body
Source Link
David
  • 57
  • 8
Loading
added 93 characters in body
Source Link
David
  • 57
  • 8
Loading
added 2866 characters in body; added 121 characters in body
Source Link
David
  • 57
  • 8
Loading
edited tags
Link
David
  • 57
  • 8
Loading
Source Link
David
  • 57
  • 8
Loading