型号
我在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是工作,但当我调用其他页面它不工作。通常它是工作时,我按下添加项目按钮,并重新启动应用程序,但现在它什么都没有。它不工作,甚至重新启动应用程序。
1条答案
按热度按时间hwazgwia1#
问题是您有多个
VM
,它们彼此之间没有关系。在@StateObject var VM = TravelViewModel()
中不能有多个source of truth
。保留
ContentView
中的视图,并将其传递给另一个视图,如下所示:VStack {....}.environmentObject(VM)
.在
AddTravelView
和RecentTravels
中,添加@EnvironmentObject var VM: TravelViewModel
而不是@StateObject var VM = TravelViewModel()
。查看此链接,它为您提供了一些很好的示例,说明如何在应用中管理数据:
https://developer.apple.com/documentation/swiftui/managing-model-data-in-your-app