对SwiftUI FetchRequest的更改不会触发视图刷新? [英] Changes to SwiftUI FetchRequest not triggering view refresh?

查看:104
本文介绍了对SwiftUI FetchRequest的更改不会触发视图刷新?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用FetchRequest包装器,并在视图内部更改获取结果的数据.第一次加载视图时,此方法有效,视图会随着所做的每一次更改进行更新.

问题是,如果我离开视图并再次返回,则对获取请求数据的更改将停止刷新视图.查看更改的唯一方法是导航并再次返回.

我正在打印获取请求,并且对数据所做的更改正在起作用,这说明了为什么如果我再次导航回去,视图将正确显示,但是当视图上的数据更改时,视图没有刷新.

这是错误还是我做错了什么?

我有一个显示所有日记的库视图,在第一部分中是一个文本字段,允许添加新日记,在第二部分中,可以选择所有日记的列表,以选中它们旁边的复选标记. /p>

第一次添加新日记并选择它们是可行的.非常奇怪的是,如果我离开并返回,它们会停止工作.


struct LibraryView: View {

    // MARK: - PROPERTIES
    @Environment(\.managedObjectContext) var context


    @FetchRequest(
      //  entity: Journal.entity(),
        sortDescriptors: [NSSortDescriptor(keyPath: \Journal.name, ascending: true)],
        animation: .default
    ) var journals: FetchedResults<Journal>


    @State private var name = ""


    // MARK: - INITIAL VIEW -
    var body: some View {

        Form {

            Section(header: Text("New Journal")) {
                HStack {

                    TextField("Name", text: $name, onCommit: {
                        let newJournal = Journal(context: self.context)
                        newJournal.name = self.name
                        try? self.context.save()
                        self.name = ""
                    })

                    Button(action: { print("ACTION") }) {
                        Image(systemName: "plus.circle.fill")
                    }
                }
            }

            Section(header: Text("Journals")) {
                ForEach(journals) { journal in
                    Button(action: {
                        journal.isSelected.toggle()
                        try? self.context.save()

                    }) {
                        HStack {
                            Text(journal.name)
                            Spacer()
                            if journal.isSelected {
                                Image(systemName: "circle.fill")
                            }
                        }
                    }
                }
            }

        }.navigationBarTitle("Library")
    }
}

日志只是一个简单的核心数据模型:


import Foundation
import CoreData

public class Journal: NSManagedObject, Identifiable {

    @NSManaged public var name: String
    @NSManaged public var isSelected: Bool

}

我从带有导航栏中导航链接的选项卡视图导航到图书馆视图":


struct JournalView: View {

    // MARK: - PROPERTIES
    @State private var presentFiltersView = false

    // MARK: - INITIAL VIEW -
    var body: some View {
        NavigationView {
            Text("Journal")
                .navigationBarTitle("Journal")
                .navigationBarItems(
                    leading: NavigationLink(destination: LibraryView()) {
                        Text("Library")
                    },
                    trailing: Button(action: { self.presentFiltersView = true }) {
                        Text("Filters")
                    })
        }.sheet(isPresented: $presentFiltersView) { Text("Filters") }
    }
}

我尝试从导航栏项中删除导航链接,并将其用作标准列表行导航链接,结果是相同的.

解决方案

我想出了为什么会这样.问题是我导航到视图的方式.原因是导航栏项中有导航链接.取而代之的是,我自己将导航链接移到了外面,并用一个控制导航链接的活动状态的按钮替换了它.提取请求现在似乎可以正常工作.

之前:

.navigationBarItems(leading:
    NavigationLink(
        destination: MyView(),
        label: {
    Text("MyView")
}))

之后:

NavigationLink(
    destination: MyView(),
    isActive: $isActive,
    label: {
        EmptyView()
})

.navigationBarItems(leading:
    Button(
        action: self.isActive = true,
        label: {
    Text("My View")
}))

Using the FetchRequest wrapper, and changing the data of the fetched results inside the view. This works the first time the view loads, the view updates with every change made..

The problem is if I navigate away from the view and back again, the changes to fetch request data stop refreshing the view. The only way to see the changes is to navigate away and back once again.

I am printing the fetch request, and changes to the data are working, which explains why if I navigate away back again the view displays correctly, but the view is not refreshing when that data is changed on the view.

Is this a bug or am I doing something incorrectly?

I have a library view that displays all journals, in the first section is a text field that allows adding a new journal, in the second section a list of all journals that can be selected to toggle a checkmark next to them.

Adding new journals and selecting them works the first time.. Very odd that they stop working if I navigate away and come back.


struct LibraryView: View {

    // MARK: - PROPERTIES
    @Environment(\.managedObjectContext) var context


    @FetchRequest(
      //  entity: Journal.entity(),
        sortDescriptors: [NSSortDescriptor(keyPath: \Journal.name, ascending: true)],
        animation: .default
    ) var journals: FetchedResults<Journal>


    @State private var name = ""


    // MARK: - INITIAL VIEW -
    var body: some View {

        Form {

            Section(header: Text("New Journal")) {
                HStack {

                    TextField("Name", text: $name, onCommit: {
                        let newJournal = Journal(context: self.context)
                        newJournal.name = self.name
                        try? self.context.save()
                        self.name = ""
                    })

                    Button(action: { print("ACTION") }) {
                        Image(systemName: "plus.circle.fill")
                    }
                }
            }

            Section(header: Text("Journals")) {
                ForEach(journals) { journal in
                    Button(action: {
                        journal.isSelected.toggle()
                        try? self.context.save()

                    }) {
                        HStack {
                            Text(journal.name)
                            Spacer()
                            if journal.isSelected {
                                Image(systemName: "circle.fill")
                            }
                        }
                    }
                }
            }

        }.navigationBarTitle("Library")
    }
}

The journal is just a simple core data model:


import Foundation
import CoreData

public class Journal: NSManagedObject, Identifiable {

    @NSManaged public var name: String
    @NSManaged public var isSelected: Bool

}

I navigate to the Library View from a Tab View with a navigation link in the navigation bar:


struct JournalView: View {

    // MARK: - PROPERTIES
    @State private var presentFiltersView = false

    // MARK: - INITIAL VIEW -
    var body: some View {
        NavigationView {
            Text("Journal")
                .navigationBarTitle("Journal")
                .navigationBarItems(
                    leading: NavigationLink(destination: LibraryView()) {
                        Text("Library")
                    },
                    trailing: Button(action: { self.presentFiltersView = true }) {
                        Text("Filters")
                    })
        }.sheet(isPresented: $presentFiltersView) { Text("Filters") }
    }
}

I have tried removed the navigation link from the nav bar item, and using it as a standard list row navigation link, results are the same.

解决方案

Think I figured out why this was happening. Problem is the way I was navigating to the view. Having a navigation link inside the navigation bar items was the cause. Instead I moved the navigation link outside on it's own, and replaced it with a button that controls the active state of the navigation link. Fetch Request seems to work as expected now.

Before:

.navigationBarItems(leading:
    NavigationLink(
        destination: MyView(),
        label: {
    Text("MyView")
}))

After:

NavigationLink(
    destination: MyView(),
    isActive: $isActive,
    label: {
        EmptyView()
})

.navigationBarItems(leading:
    Button(
        action: self.isActive = true,
        label: {
    Text("My View")
}))

这篇关于对SwiftUI FetchRequest的更改不会触发视图刷新?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆