当 Userdefaults 中的对象更改时更新 SwiftUI 视图

问题描述

我正在 XCode 中开发一个应用程序,该应用程序显示保存在来自 URL 的 JSON 文件中的位置。 我已经在 UserDefaults.standard.object(forKey: "heart") 中保存了用户最喜欢的位置

SpotDetailView 上的心形按钮可保存该点并显示它是否为收藏。

import SwiftUI

struct SpotDetailView: View {
    @State var spot: WindApp //kNows which spot it's at
    var spotname:String
    @State var favourites: [String:String] = UserDefaults.standard.object(forKey: "heart") as? [String:String] ?? [:]
    
    
    var body: some View {
        
        ZStack {
            
            List {
                SpotMapView(coordinate: spot.locationCoordinate)
                    .cornerRadius(8)
                ForEach(0..<9) { i in
                    SingleDayView(spot: spot,counter: (i * 8))
                    }
            }
            .navigationTitle("\(spot.spot)")
            vstack {
                Spacer()
                HStack {
                    Spacer()
                    Button(action: {
                        if favourites[spot.spot] == "heart" {
                            favourites[spot.spot] = "heart.fill"
                            UserDefaults.standard.set(favourites,forKey: "heart")
                        }
                        else if favourites[spot.spot] == "heart.fill" {
                            favourites[spot.spot] = "heart"
                            UserDefaults.standard.set(favourites,forKey: "heart")
                        }
                        else {
                            favourites[spot.spot] = "heart.fill"
                            UserDefaults.standard.set(favourites,forKey: "heart")
                        }

                    },label: {
                        Image(systemName: favourites[spot.spot] ?? "heart")
                    })
             
                }
            }
        }
    }
}

但是,当尝试访问主概览上的数据时,它会在重新/启动应用程序后工作,但在子视图中更改时不会更新。

struct AllSpotsView: View {
    @State private var spotData = [WindApp]()
    @State var favourites: [String: String] = UserDefaults.standard.object(forKey: "heart") as? [String: String] ?? [:]


    
    var body: some View {
        ZStack {
            NavigationView{
                List(spotData,id: \.spot) {
                    item in
                    NavigationLink(destination: SpotDetailView(spot: item,spotname: item.spot)) {
                        HStack() {
                            Text(item.spot)
                            
                            Text(item.country_code)
                                .font(.caption2)
                                .foregroundColor(.gray)
                            Spacer()
                            Image(systemName: favourites[item.spot] ?? "heart" )
                            
                        }
                        
                    }.navigationBarTitle("Spots")
                    
                }.onAppear(perform: loadData)
                
                
            }
                
        }
    }
}

函数 loadData 只是从 URL 加载 JSON 文件。 一旦 Userdefault 值更改,如何更新视图? 提前致谢!

解决方法

代替

@State var favourites: [String: String] = UserDefaults.standard.object(forKey: "heart") as? [String: String] ?? [:]

使用

@AppStorage("heart") var favourites: [String: String] = [:]
,

你将你的属性标记为@Observable。通过这样做,UI 将观察属性值的变化并自行更新。