英文:
SwiftUI Save ManagedObjectContext after Toggle
问题
在我的SwiftUI / iOS 15+应用程序中,我有一个工具栏,显示一个按钮,该按钮用于切换“item”对象的“bookmarked”属性。该项目以Binding方式传递,如下所示:
import SwiftUI
struct PageViewToolbar: ToolbarContent {
@Environment(\.managedObjectContext) var context
@Binding var item: Item // CoreData ManagedObject
var body: some ToolbarContent {
ToolbarItem(placement: .automatic) {
Toggle(isOn: self.$item.bookmarked) {
Image(systemName: "bookmark")
.symbolVariant(self.item.bookmarked ? .fill : .none)
} //Toggle
.toggleStyle(.button)
.onChange(of: item.bookmarked) { newValue in
if context.hasChanges {
do {
try context.save()
} catch {
print("Error saving context: \(error)")
}
}
}
} //ToolbarItem
} //body
} //PageViewToolbar
按钮正在切换,项目的“bookmarked”属性也相应地设置了,但项目是CoreData ManagedObject,所以每当属性更改时,我需要触发上下文保存。有没有办法将这个逻辑附加到Toggle按钮上?
英文:
In my SwiftUI / iOS 15+ app, I have a toolbar displaying a button which is meant to toggle the "bookmarked" property of an "item" object. The item is passed in as a Binding, as shown here:
import SwiftUI
struct PageViewToolbar: ToolbarContent {
@Environment(\.managedObjectContext) var context
@Binding var item: Item //CoreData ManagedObject
var body: some ToolbarContent {
ToolbarItem(placement: .automatic) {
Toggle(isOn: self.$item.bookmarked) {
Image(systemName: "bookmark")
.symbolVariant(self.item.bookmarked ? .fill : .none)
} //Toggle
.toggleStyle(.button)
} //ToolbarItem
} //body
} //PageViewToolbar
The button is toggling and the bookmarked property on the item is being set accordingly, but item is a CoreData ManagedObject and so I need to trigger a context save whenever the property is changed. Is there a way to attach that logic to the Toggle button?
答案1
得分: 2
首先,item
是引用类型,因此您必须使用 @ObservedObject
而不是 @Binding
来获取关于更改的通知。幸运的是,NSManagedObject
默认符合 ObservableObject
。
然后,添加 .onChange
修饰符,以在 bookmarked
更改时保存上下文。
struct PageViewToolbar: ToolbarContent {
@Environment(\.managedObjectContext) var context
@ObservedObject var item: Item
var body: some ToolbarContent {
ToolbarItem(placement: .automatic) {
Toggle(isOn: $item.bookmarked) {
Image(systemName: "bookmark")
.symbolVariant(item.bookmarked ? .fill : .none)
} //Toggle
.toggleStyle(.button)
.onChange(of: item.bookmarked) { _ in
try? context.save()
}
} //ToolbarItem
} //body
} //PageViewToolbar
英文:
First of all item
is reference type so you must use @ObservedObject
rather than @Binding
to get notified about changes. Fortunately NSManagedObject
conforms to ObservableObject
by default.
Then add the .onChange
modifier to save the context when bookmarked
has changed.
struct PageViewToolbar: ToolbarContent {
@Environment(\.managedObjectContext) var context
@ObservedObject var item: Item
var body: some ToolbarContent {
ToolbarItem(placement: .automatic) {
Toggle(isOn: $item.bookmarked) {
Image(systemName: "bookmark")
.symbolVariant(item.bookmarked ? .fill : .none)
} //Toggle
.toggleStyle(.button)
.onChange(of: item.bookmarked) { _ in
try? context.save()
}
} //ToolbarItem
} //body
} //PageViewToolbar
答案2
得分: -1
import SwiftUI
struct PageViewToolbar: ToolbarContent {
@Environment(\.managedObjectContext) var context
@State var bookmarked: Bool
@Binding var item: Item // CoreData ManagedObject
init(item: Binding<Item>) {
_item = item
bookmarked = item.wrappedValue.bookmarked
}
var body: some ToolbarContent {
ToolbarItem(placement: .automatic) {
Toggle(isOn: $bookmarked) {
Image(systemName: "bookmark")
.symbolVariant(self.bookmarked ? .fill : .none)
} //Toggle
.toggleStyle(.button)
} //ToolbarItem
.onChange(of: item) { newValue in
bookmarked = newValue.bookmarked
}
.onChange(of: bookmarked) { newValue in
guard item.bookmarked != newValue else { return }
item.bookmarked = newValue
try? context.save()
}
} //body
} //PageViewToolbar
英文:
import SwiftUI
struct PageViewToolbar: ToolbarContent {
@Environment(\.managedObjectContext) var context
@State var bookmarked: Bool
@Binding var item: Item //CoreData ManagedObject
init(item: Binding<Item>) {
_item = item
bookmarked = item.wrappedValue.bookmarked
}
var body: some ToolbarContent {
ToolbarItem(placement: .automatic) {
Toggle(isOn: $bookmarked) {
Image(systemName: "bookmark")
.symbolVariant(self.bookmarked ? .fill : .none)
} //Toggle
.toggleStyle(.button)
} //ToolbarItem
.onChange(of: item) { newValue in
bookmarked = newValue.bookmarked
}
.onChange(of: bookmarked) { newValue in
guard item.bookmarked != newValue else { return }
item.bookmarked = newValue
try? context.save()
}
} //body
} //PageViewToolbar
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论