SwiftUI 切换后保存 ManagedObjectContext

huangapple go评论47阅读模式
英文:

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&lt;Item&gt;) {
        _item = item
        bookmarked = item.wrappedValue.bookmarked
    }
    
    var body: some ToolbarContent {
        ToolbarItem(placement: .automatic) {
            Toggle(isOn: $bookmarked) {
                Image(systemName: &quot;bookmark&quot;)
                    .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

huangapple
  • 本文由 发表于 2023年6月18日 22:45:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/76501104.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定