【问题标题】:Trying to keep a list up-to-date in a SwiftUI app尝试在 SwiftUI 应用程序中使列表保持最新
【发布时间】:2021-11-29 09:30:55
【问题描述】:

我在使用 SwiftUICoreData 时遇到了一些问题。 我的应用有一个来自核心数据实体的项目列表。

启动项目时 Xcode 提供的初始(模板)代码 - 工作。

但是当我想设置一个谓词来选择应该列出哪些项目时,问题就来了。

此时我可以让应用程序从给定的选择开始。 换句话说,我可以设置一个谓词开始。

在应用程序运行以选择要列出的不同项目集时更新谓词时会出现问题。

下面是代码当前的样子:

import SwiftUI
import CoreData

struct ContentView: View {
    @Environment(\.managedObjectContext) private var viewContext
    .....
    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \TheEntity. sortField, ascending: true)],
        animation: .default)

    private var items: FetchedResults<TheEntity>
    @FetchRequest var items: FetchedResults<TheEntity>
    .....
    init() {
        let cntxt = PersistenceController.shared.container. viewContext,
            theMedia = HearText.currentMedia(inMOContext: cntxt),
            predicate = NSPredicate(format: "media==%@", theMedia)

        self._items = FetchRequest(entity: TheEntity.entity(),
                                   sortDescriptors: 
                                    [NSSortDescriptor(keyPath:  \TheEntity.sortField,
                                                      ascending:    true)],
                                   predicate: predicate)
    }
    .....
}

它正在工作,除了当 currentMedia() 由于应用程序内部的某些操作而返回不同的值时,列表不会相应地更新。

虽然我已经尝试了一些解决方案,但目前我没有任何效果。必须有办法解决这个问题,但我的主要问题是无法在 init() 中使用任何实例变量。任何有关如何处理此问题的相关提示都将受到高度赞赏。

【问题讨论】:

  • 这里的主要问题是currentMedia 是一个你调用的函数但是你怎么知道什么时候调用它,你怎么知道它会返回一个不同的结果?我会考虑将获取请求移动到符合 ObservableObject 的类中,并将结果数组设为 @Published 属性,但由于我之前的问题,我不知道如何使其工作。旁注,请不要在代码中添加额外的空格,特别是在. 之后,因为这会使代码更难阅读,而且在初始化时你会得到一个 viewContext ,这是没有意义的,因为你有 viewContext 作为@Environment 属性跨度>
  • 我知道什么时候只是因为我知道在我的应用程序中导致更改的原因(这是问题的简单部分)。您对 viewContext 作为@Environment 属性的评论在此处不起作用(),因为无法访问 init 中的实例变量。这正是我这样做的原因。
  • 我看过那篇文章,但认为它在这里没有帮助,但它确实有用。当您没有解释时,对您来说容易的事情对我们来说并不那么容易,现在不那么重要,但也许考虑一下未来的任何问题。最后,如果问题已得到解答,那么最好发布您的解决方案或删除问题。
  • @Joakim_Danielson。你完全正确。实际上,我必须根据自己的需要定制文章,但这显然给了我正确的冲动。我打算发布我自己的答案,提到这篇文章。但是这个评论是同时出现的,所以我想成为票价并给予信任。

标签: ios swift core-data nsfetchrequest swiftui-list


【解决方案1】:

我的猜测是 currentMedia() 使用 .items 没有向 SwiftUI 显示它们之间的依赖关系。

您可以将items 变量传递给函数currentMedia(items: items),而不是直接从currentMedia 函数内部访问items 变量。这会在 items 和函数之间创建依赖关系,使 SwiftUI 重新调用 currentMedia 以防 items 变量被刷新。请注意,这是有效的,因为.items 会通知 SwiftUI,以防它在 View 正文中使用。

这与依赖于用户输入的动态过滤器类似。如果过滤器与谓词一起应用,则更改@FetchRequest 上的谓词。如果过滤器对生成的items 起作用,则将过滤器变量存储在@State@Published 变量中,并将它们传递给currentMedia 以查看currentMedia 在它们更改时调用。将过滤器变量存储在 @State@Published 中并在 View 主体中使用它们可以让 SwiftUI 看到更改通知,并使 SwiftUI 重新评估 View 主体,从而允许 View 重新绘制过滤器更改。

【讨论】:

    猜你喜欢
    • 2021-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多