我在CoreData SwiftUI项目中有以下代码:
import SwiftUI
struct ContentView: View {
@FetchRequest(entity: TestObject.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \TestObject.name, ascending: true)]) var objects: FetchedResults<TestObject>
@Environment(\.managedObjectContext) var managedObjectContext
@State private var showFavorites = true
var body: some View {
NavigationView {
List {
if(showFavorites) {
Section(header: Text("Favorites").font(.headline).padding(.leading, -8)) {
ForEach(self.objects.filter({ (testObj) -> Bool in
return testObj.isFavorite
}), id: \.id) { obj in
NavigationLink(destination: DetailsView(testObject: obj)) {
Text(obj.name ?? "")
}
}
}
}
Section(header: Text("All").font(.headline).padding(.leading, -8)) {
ForEach(self.objects, id: \.id) { obj in
NavigationLink(destination: DetailsView(testObject: obj)) {
Text(obj.name ?? "")
}
}
}
}.listStyle(GroupedListStyle())
.environment(\.horizontalSizeClass, .regular)
.navigationBarTitle("Test", displayMode: .large)
.navigationBarItems(
trailing: Button(action: {
let newObj = TestObject(context: self.managedObjectContext)
newObj.name = "newTest"
newObj.id = UUID()
newObj.isFavorite = false
do {
try self.managedObjectContext.save()
} catch let error {
print(error)
print("error saving object")
}
}) {
Image(systemName: "plus")
}
)
}
}
}
struct DetailsView : View{
@ObservedObject var testObject : TestObject
var body : some View {
VStack {
Text(testObject.name ?? "")
}.navigationBarTitle("Detail")
.navigationBarItems(
trailing: HStack {
Button(action: {
self.testObject.isFavorite.toggle()
}) {
Image(systemName: self.testObject.isFavorite ? "heart.fill" : "heart")
}
}
)
}
}
xcdatamodeld文件中的这个实体:
如果我是第一次启动该应用程序,则可以通过单击NavigationBar中的加号图像来添加新的TestObject,然后将其添加到列表中。如果再点击其中一个对象,则导航到DetailsView。在此视图上,用心脏点击NavigationBarButton会将对象标记为收藏,这样,如果用户向后导航,则在列表(收藏)中也将显示在第一部分中。到目前为止,它仍然有效,但是我有这种奇怪的效果:
“收藏夹”部分中多余元素的NavigationLink似乎会自动触发。知道我该如何解决吗?
预先感谢
答案 0 :(得分:0)
尝试以下操作(无法测试您的代码,所以只是一个想法)
struct DetailsView : View {
@ObservedObject var testObject : TestObject
@State private var isFavorite: Bool
init(testObject: TestObject) {
self.testObject = testObject
_isFavorite = State(initialValue: testObject.isFavorite)
}
var body : some View {
VStack {
Text(testObject.name ?? "")
}.navigationBarTitle("Detail")
.navigationBarItems(
trailing: HStack {
Button(action: {
self.isFavorite.toggle()
}) {
Image(systemName: self.isFavorite ? "heart.fill" : "heart")
}
}
)
.onDisappear {
DispatchQueue.main.async { // << this might be redundant, try w/ and w/o
self.testObject.isFavorite = self.isFavorite
}
}
}
}