ios 数据未保存或加载,因为我正在从其他页面调用数据

ehxuflar  于 2022-11-19  发布在  iOS
关注(0)|答案(1)|浏览(95)

型号
我在Travel中有不同的变量。

import Foundation

struct Travel: Identifiable, Codable {
    var id = UUID()
    var name: String
    var date = Date()
    var location: String
    var isFav: Bool
    var score: Float
    var comment: String
}

查看模型
我用UserDefaults加载和保存数据。它总是起作用,但在这个模型中不起作用。

import Foundation

class TravelViewModel: ObservableObject {
    @Published var travelList = [Travel] ()
    @Published var travelled = 0
    
    init(){
        load()
    }
    
    func load() {
        guard let data = UserDefaults.standard.data(forKey: "travelList"),
              let savedTravels = try? JSONDecoder().decode([Travel].self, from: data) else { travelList = []; return }
        
        travelList = savedTravels
    }
    
    func save() {
        do {
            let data = try JSONEncoder().encode(travelList)
            UserDefaults.standard.set(data, forKey: "travelList")
        } catch {
            print(error)
        }
    }
    
}

添加项目视图
我有addItems函数,并在addItem按钮中使用此函数。

import SwiftUI

struct AddTravelView: View {
    
    @StateObject var VM = TravelViewModel()
    
    @State var name = ""
    @State var location = ""
    @State var isFav = false
    @State var score = 0.00
    @State var comment = ""
    
    var body: some View {
        VStack {
            ZStack {
                Rectangle()
                    .fill(.black.opacity(0.2))
                    .cornerRadius(20)
                    .frame(width: 350, height: 350)
                VStack{
                    HStack {
                        Text("Name:")
                            .font(.system(size: 16 , weight: .medium))
                        TextField("Type..", text: $name)
                    }
                    HStack {
                        Text("Location:")
                            .font(.system(size: 16 , weight: .medium))
                        TextField("Type..", text: $location)
                    }
                    HStack {
                        Text("Score: \(Int(score))")
                            .font(.system(size: 16 , weight: .medium))
                        Slider(value: $score, in: 0...10, step: 1)
                    }
                    Spacer()
                    
                    ZStack(alignment: .topLeading) {
                        Rectangle()
                            .fill(.white)
                            .cornerRadius(20)
                            .frame(height: 200)
                        VStack(alignment: .leading) {
                            TextField("Comment...", text: $comment, axis: .vertical)
                        }.padding()
                    }
                }
                .padding()
                .frame(width: 300, height: 200)
            }
            
            Button {
                addTravel()
            } label: {
                ZStack{
                    Rectangle()
                        .fill(.black.opacity(0.2))
                        .cornerRadius(20)
                        .frame(width: 350 , height: 100)
                        
                    
                    Text("ADD TRAVEL")
                        .font(.system(size: 25, weight: .medium, design: .monospaced))
                        .foregroundColor(.black)
                }.padding()
            }

            
        }
    }
    
    func addTravel(){
        VM.travelList.append(Travel(name: name, location: location, isFav: isFav, score: Float(score), comment: comment))
    }
    
}

struct AddTravelView_Previews: PreviewProvider {
    static var previews: some View {
        AddTravelView()
    }
}

“最近添加”视图
在此页面中,我想查看之前添加的项目

import SwiftUI

struct RecentTravels: View {
    
    @StateObject var VM = TravelViewModel()
    
    var body: some View {
        VStack {
            ForEach(VM.travelList) {Travel in
                HStack{
                    Image(systemName: "questionmark")
                        .frame(width: 50, height: 50)
                        .padding()
                        .overlay {
                            RoundedRectangle(cornerRadius: 5)
                                .stroke(.black, lineWidth: 2)
                        }
                    VStack(alignment: .leading) {
                        Text(Travel.name)
                            .font(.subheadline)
                            .bold()
                            .lineLimit(1)
                        Text("\(Travel.date)")
                            .font(.footnote)
                            .opacity(0.9)
                            .lineLimit(1)
                    }
                    
                    Spacer()
                    VStack {
                        Image(systemName: "heart")
                        Spacer()
                        Text("\(Travel.score)")
                    }
                    .frame(height: 50)
                    .font(.system(size: 22))
                    
                }
            }
        }
    }
}

struct RecentTravels_Previews: PreviewProvider {
    static var previews: some View {
        RecentTravels()
    }
}

和内容视图
并在ContentView中调用这两个视图。

import SwiftUI

struct ContentView: View {
    
    @StateObject var VM = TravelViewModel()
    
    var body: some View {
        VStack {
            
            AddTravelView()
            
            RecentTravels()
        }
        .padding()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

当我写的所有代码只有ContentView是工作,但当我调用其他页面它不工作。通常它是工作时,我按下添加项目按钮,并重新启动应用程序,但现在它什么都没有。它不工作,甚至重新启动应用程序。

hwazgwia

hwazgwia1#

问题是您有多个VM,它们彼此之间没有关系。在@StateObject var VM = TravelViewModel()中不能有多个source of truth
保留ContentView中的视图,并将其传递给另一个视图,如下所示:VStack {....}.environmentObject(VM) .
AddTravelViewRecentTravels中,添加@EnvironmentObject var VM: TravelViewModel而不是@StateObject var VM = TravelViewModel()
查看此链接,它为您提供了一些很好的示例,说明如何在应用中管理数据:
https://developer.apple.com/documentation/swiftui/managing-model-data-in-your-app

相关问题