新手 Swift:我不确定为什么不显示用户的名字? Swift UI

New To Swift: Im not sure why the names of the users are not displaying? Swift UI

所以我创建了这个项目来学习 Swift Ui 但我被卡住了。我不明白为什么 HomeView 不显示联系人姓名。我创建了 ContactModel 来存储联系人详细信息,并创建了 ContactViewModel 来存储 userDefaults.I 中的所有联系人,并将信息存储在 UserDefaults 中,但由于某种原因它无法正常工作。我添加了 Xcode 项目中的所有文件。感谢您的帮助!

@main
struct ContactsAppApp: App {
    @StateObject var contactViewModel: ContactViewModel = ContactViewModel()
    
    var body: some Scene {
        WindowGroup {
            NavigationView{
                ContentView()
            }
            .environmentObject(contactViewModel)
           
        }
    }
}
    struct ContentView: View {
    var body: some View {
        TabView{
            HomeView()
                .tabItem {
                    Image(systemName: "house")
                        .foregroundColor(.white)
                    Text("home")
                }
            AddContactView()
                .tabItem{
                    Image(systemName: "laptopcomputer")
                    Text("work")
                }
        }
        
    }
}




struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
struct ContactModel: Identifiable, Codable {
let id: String
let name: String
let phoneNumber: String
let email: String

init(id: String = UUID().uuidString, name: String, phoneNumber: String, email: String) {
    self.id = id
    self.name =  name
    self.phoneNumber = phoneNumber
    self.email = email
}

func updateCompletion() -> ContactModel {
    return ContactModel(id: id, name: name, phoneNumber: phoneNumber, email: email)
}

}

class ContactViewModel: ObservableObject {

@Published var items: [ContactModel] = [] {
    didSet {
        saveItems()
    }
}

let itemsKey: String = "items_list"

init() {
    getItems()
}

func getItems() {
    guard
        let data = UserDefaults.standard.data(forKey: itemsKey),
        let savedItems = try? JSONDecoder().decode([ContactModel].self, from: data)
    else { return }

    self.items = savedItems
}

func deleteItem(indexSet: IndexSet) {
    items.remove(atOffsets: indexSet)
}

func moveItem(from: IndexSet, to: Int) {
    items.move(fromOffsets: from, toOffset: to)
}

func addItem(name: String, phoneNumber: String, email: String) {
    let newItem = ContactModel(name: name, phoneNumber: phoneNumber, email: email)
    items.append(newItem)
}

func updateItem(item: ContactModel) {
    if let index = items.firstIndex(where: { [=16=].id == item.id }) {
        items[index] = item.updateCompletion()
    }
}

func saveItems() {
    if let encodedData = try? JSONEncoder().encode(items) {
        UserDefaults.standard.set(encodedData, forKey: itemsKey)
    }
}

}


import SwiftUI

struct HomeView: View {
    @EnvironmentObject var contactViewModel: ContactViewModel
    
    var body: some View {
        NavigationView {
            VStack {
                HStack{
                    Text("Contacts")
                        .font(.system(size: 35, weight: .bold))
                        .padding(.leading,30)
                        .padding(.top,20)
                        .foregroundColor(.white)
                    Spacer()
                }
                
                Spacer()
                
                ScrollView{
                    
                    ForEach(contactViewModel.items) { item in
                        contactWidget(name: item.name)
                    }
                        
                        
                }
                .padding(.top,20)
                
                Button(action: {
                    print("touched")
                }, label: {
                    NavigationLink(destination: AddContactView().navigationBarBackButtonHidden(true)) {
                        HStack{
                            ZStack{
                            RoundedRectangle(cornerRadius: 40)
                                .frame(width: 200, height: 50)
                                .foregroundColor(.blue)
                            Text("Add Contact")
                                    .foregroundColor(.white)
                            }
                        }
                      
                    }
                    .navigationBarHidden(true)
                })
               
            }
            .background(.black)
        }
        .navigationBarHidden(true)
      
       
    }
}

struct contactWidget : View{
    let name: String
    var body: some View{
        ZStack {
            RoundedRectangle(cornerRadius: 20)
                .frame(width: 350, height: 100)
            .foregroundColor(.gray)
            HStack {
                Image(systemName: "person")
                    .resizable()
                    .clipShape(Circle())
                .frame(width: 40, height: 40)
                Text(name)
                    .font(.system(size: 18, weight: .semibold))
                Spacer()
                HStack{
                    Circle()
                    .frame(width: 40, height: 40)
                    .foregroundColor(.orange)
                    Circle()
                    .frame(width: 40, height: 40)
                    .foregroundColor(.blue)
                    Circle()
                    .frame(width: 40, height: 40)
                    .foregroundColor(.pink)
                }
                
            }
            .padding(.leading,40)
            .padding(.trailing,30)
            
        }
    }
}

struct HomeView_Previews: PreviewProvider {
    static var previews: some View {
        NavigationView{
            HomeView()
        }
        .environmentObject(ContactViewModel())
    }
}
import SwiftUI

struct AddContactView: View {
    @EnvironmentObject var contactViewModel: ContactViewModel
    @State var contactName: String = ""
    @State var phoneNumber: String = ""
    @State var email: String = ""
    
    
    var body: some View {
        NavigationView {
            VStack {
                HStack{
                    Text("Contacts")
                        .font(.system(size: 35, weight: .bold))
                        .padding(.leading,30)
                        .padding(.top,20)
                        .foregroundColor(.white)
                    Spacer()
                }
                
                TextField("Enter name", text: $contactName)
                    .frame(width: 330, height: 30)
                    .padding()
                    .background(.white)
                    
                    .cornerRadius(10)
                
                TextField("Enter Phone Number", text: $phoneNumber)
                    .frame(width: 330, height: 30)
                    .padding()
                    .background(.white)
                    
                    .cornerRadius(10)
                
                TextField("Enter Email", text: $email)
                    .frame(width: 330, height: 30)
                    .padding()
                    .background(.white)
                    
                    .cornerRadius(10)
                
                Text(contactName)
                    .foregroundColor(.white)
                    
                
        
                Spacer()
                
                
                .padding(.top,20)
                
                Button(action: {
                    contactViewModel.addItem(name: contactName, phoneNumber: phoneNumber, email: email)
                    
                    contactName = ""
                    phoneNumber = ""
                    email = ""
                    
                }, label: {
                    NavigationLink(destination: HomeView().navigationBarBackButtonHidden(true)) {
                        HStack{
                            ZStack{
                            RoundedRectangle(cornerRadius: 40)
                                .frame(width: 200, height: 50)
                                .foregroundColor(.blue)
                            Text("Done")
                                    .foregroundColor(.white)
                            }
                        }
                      
                    }
                    .navigationBarHidden(true)
                })
               
            }
            .background(.black)
        }
        .navigationBarHidden(true)
      
       
    }
}



struct AddContactView_Previews: PreviewProvider {
    static var previews: some View {
        NavigationView{
            AddContactView()
        }
        .environmentObject(ContactViewModel())
    }
}

“...HomeView 不显示联系人姓名...”的原因是 因为 AddContactView 中的按钮标签内有 NavigationLink(destination: HomeView()....。也就是说,点击被 NavigationLink 并在不执行按钮操作的情况下转到 HomeView 添加联系人, contactViewModel.addItem( ...)。所以重组你的代码 NavigationLink在它之外。

下面的示例代码应该可以解决您的问题。

struct AddContactView: View {
    @EnvironmentObject var contactViewModel: ContactViewModel
    @State var contactName: String = ""
    @State var phoneNumber: String = ""
    @State var email: String = ""
    
    @State var goHome = false  // <-- here
    
    var body: some View {
        NavigationView {
            VStack {
                HStack{
                    Text("Contacts")
                        .font(.system(size: 35, weight: .bold))
                        .padding(.leading,30)
                        .padding(.top,20)
                        .foregroundColor(.white)
                    Spacer()
                }
                TextField("Enter name", text: $contactName)
                    .frame(width: 330, height: 30)
                    .padding()
                    .background(.white)
                    .cornerRadius(10)
                
                TextField("Enter Phone Number", text: $phoneNumber)
                    .frame(width: 330, height: 30)
                    .padding()
                    .background(.white)
                    .cornerRadius(10)
                
                TextField("Enter Email", text: $email)
                    .frame(width: 330, height: 30)
                    .padding()
                    .background(.white)
                    .cornerRadius(10)
                
                Text(contactName).foregroundColor(.white)
                
                Spacer().padding(.top,20)
                
                Button(action: {
                    contactViewModel.addItem(name: contactName, phoneNumber: phoneNumber, email: email)
                    
                    contactName = ""
                    phoneNumber = ""
                    email = ""
                    
                    goHome = true  // <-- here
                }, label: {
                    HStack{
                        ZStack{
                            RoundedRectangle(cornerRadius: 40)
                                .frame(width: 200, height: 50)
                                .foregroundColor(.blue)
                            Text("Done")
                                .foregroundColor(.white)
                        }
                    }
                })
                
                // -- here
                NavigationLink(destination: HomeView().navigationBarBackButtonHidden(true), isActive: $goHome) {
                    EmptyView()
                }.navigationBarHidden(true)
                
            }
            .background(.black)
        }
        .navigationBarHidden(true)
    }
}

类似HomeView中的按钮,或者去掉Button部分,只保留NavigationLink