当 UserDefaults 值更改 SwiftUI 时,@FetchRequest 谓词不会更新

Posted

技术标签:

【中文标题】当 UserDefaults 值更改 SwiftUI 时,@FetchRequest 谓词不会更新【英文标题】:@FetchRequest predicate not updating when UserDefaults value changes SwiftUI 【发布时间】:2022-01-07 06:52:24 【问题描述】:

我无法弄清楚如何让 SwiftUI @FetchRequest 仅在 UserDefaults 中存储的布尔值是 true 时才使用谓词。

问题在于FetchedResults 的值在showAvailable 的值更改时没有更改。目前我必须重新启动应用程序才能看到基于 showAvailable 值的结果。

struct ContentView: View 

@AppStorage("showAvailable") private var showAvailable : Bool = false


@FetchRequest private var list: FetchedResults<Item>



init() 
        @AppStorage("showAvailable") var showAvailable : Bool = false
        _list = FetchRequest(
            sortDescriptors: [],
            predicate: showAvailable ? NSPredicate(format: "parent == nil") : nil,
            animation: .default
        )


var body: some View 
     Button("Cancel") 
        showAvailable.toggle()
     

【问题讨论】:

【参考方案1】:

我会在 Button 操作中使用新谓词更新获取请求,并且该更新应该会触发请求再次执行

struct ContentView: View 
    @AppStorage("showAvailable") private var showAvailable : Bool = false

    @FetchRequest(sortDescriptors: [], 
                  predicate: NSPredicate(value: true)
                  animation: .default)
    private var list: FetchedResults<Item>

    var body: some View 
        Button("Cancel") 
            showAvailable.toggle()
            updatePredicate()
        
        .onAppear 
            updatePredicate()
        
    

    private func updatePredicate() 
        if showAvailable 
            list.nspredicate = NSPredicate(format: "parent == nil")
         else 
            list.nspredicate = NSPredicate(value: true)
                
    

【讨论】:

这可以完美运行,但现在该结构的初始化不是基于showAvailable bool。理想情况下,我希望应用程序在重新启动时“记住”showAvailable 值。关于如何做到这一点的任何想法? 将整个if showAvaliable... 部分移动到一个单独的函数中,并从.onAppear 调用它

以上是关于当 UserDefaults 值更改 SwiftUI 时,@FetchRequest 谓词不会更新的主要内容,如果未能解决你的问题,请参考以下文章

检索 UserDefaults 后在 viewdidload 上刷新 collectionView

保存到 UserDefaults 被调用 19 次

从 UserDefaults 中提取 Picker

从 UserDefaults 获得的布尔值打印为 0 或 1,即使保存为 Any

UserDefaults 在 SwiftUI 中与 Toggle 绑定

从特定的核心数据表行中检索值 - 然后将值存储到 UserDefaults