SwiftUI @AppStorage 不在函数中刷新

Posted

技术标签:

【中文标题】SwiftUI @AppStorage 不在函数中刷新【英文标题】:SwiftUI @AppStorage doesn't refresh in a function 【发布时间】:2021-06-01 12:54:13 【问题描述】:

我试图在每个 .onAppear 中重新加载数据,但如果我在 SettingsView 中更改 @AppStorage nearMeter 的值,它不会更新 reloadNearStops 函数中的值并使用之前的 @AppStorage 值。

    struct SettingsView: View 
        @AppStorage(“nearMeter”) var nearMeter: Int = 1
        @State var meters = ["100 m","200 m","400 m","500 m","750 m","1 km"]
    
    var body: some View 


    ………
    
                            Picker(selection: $nearMeter, label: HStack 
                                    Text(NSLocalizedString(“near_stops_distance”, comment: ""))
                            ) 
                                ForEach(0 ..< meters.count, id: \.self) 
                                        Text(meters[$0])
                                
                            



    struct FavouritesView: View 
 @AppStorage(“nearMeter”) var nearMeter: Int = 1
        
            func reloadNearStops(nearMeter: Int) 
                
                print(nearMeter)
                readNearStopsTimeTable.fetchTimeTable(nearMeter:        getLonLatSpan(nearMeter: nearMeter), lat: (locationManager.lastLocation?.coordinate.latitude)!, lon: (locationManager.lastLocation?.coordinate.longitude)!)
            
            
            
            func getLonLatSpan(nearMeter: Int) -> Double 
                let meters = [100,200,400,500,750,1000]
                
                if nearMeter < meters.count 
                    return Double(meters[nearMeter]) * 0.00001
                
                else 
                    return 0.001
                
            
        var body: some View 
    
      
    .....
        
        ……….
        .onAppear() 
                    
                    if locationManager.lastLocation?.coordinate.longitude != nil 
                            if hasInternetConnection 
                                reloadNearStops(nearMeter: nearMeter)
                            
                    
        
        

【问题讨论】:

不应该。它只能在 SwiftUI 视图中。 @Asperi 更新代码:AppStorage 在我看来,功能也在 任何动态属性都应该在body 的某个地方使用以进行更新(重新获取)。 【参考方案1】:

AppStorage 不会调用函数,但onChange 可以在AppStorage 发生变化时调用函数。

struct StorageFunctionView: View 
    @AppStorage("nearMeter") var nearMeter: Int = 1
    @State var text: String = ""
    var body: some View 
        VStack
            Text(text)
            Button("change-storage", action: 
                nearMeter = Int.random(in: 0...100)
            )
        
        //This will listed for changes in AppStorage
        .onChange(of: nearMeter, perform:  newNearMeter in
            //Then call the function and if you need to pass the new value do it like this
            fetchSomething(value: newNearMeter)
        )
    
    func fetchSomething(value: Int)  
        text = "I'm fetching \(value)"
    

【讨论】:

以上是关于SwiftUI @AppStorage 不在函数中刷新的主要内容,如果未能解决你的问题,请参考以下文章

使用 @AppStorage 进行设置的 SwiftUI 最佳实践:如何在加载 @AppStorage 之前读取 UserDefaults?

更新单独结构中的@AppStorage 后如何更新 SwiftUI 视图

SwiftUI - AppStorage 不适用于 GeometryReader

SwiftUI 中的可模拟 @AppStorage

如何让@AppStorage 在 MVVM / SwiftUI 框架中工作?

SwiftUI:你可以将 AppStorage 与解码的 json 一起使用吗?