首页 > 解决方案 > 关于 SwiftUI 视图和 CoreData 的两个问题

问题描述

我有 2 个具有父子关系的 CoreData 对象。我需要列出所有孩子并通过点击按钮添加孩子。新的孩子必须在点击后立即出现在列表中。

下面是实验视图的代码。如您所见,它显示了包含在父对象中的子对象列表。它以 2 种方式添加新子项:1)立即在按钮操作中和 2)使用 .actionSheet 修饰符进行确认。

问题是:

  1. 为什么方法2添加后刷新列表而方法1没有?
  2. 如何让方法 1 起作用(无需确认即可添加)?
struct ObjectEditorView: View {

    init(editingObject parent: ParentObjectEntity? = nil)
    {
        let context = NSManagedObjectContext.main.newChildViewContext()

        self._editingObject = State(initialValue: {
            if let parent = parent
            {
                return (context.object(with: parent.objectID) as! ParentObjectEntity)
            }
            else
            {
                return ParentObjectEntity(context: context)
            }
        }())

        editingContext = context
    }

    @State var editingObject: ParentObjectEntity

    private let editingContext: NSManagedObjectContext

    @State private var addingItem = false

    fileprivate func AddChild()
    {
        let order = editingObject.orderedChildren.count

        let child = ChildObjectEntity(context: editingContext)

        child.parent = editingObject

        child.title = "Child \(order + 1)"
        child.order = Int16(order)
    }

    var body: some View {
        NavigationView
        {
            VStack
            {
                HStack
                {
                    Spacer()

                    Button(action: { addingItem = true })
                    {
                        Label("Method 1", systemImage: "plus")
                    }

                    Button(
                        action:
                        {
                            AddChild()
                        })
                    {
                        Label("Method 2", systemImage: "plus")
                    }
                }
                .padding()

                List
                {
                    ForEach(editingObject.orderedChildren, id: \.self)
                    { item in
                        NavigationLink(
                            destination: Text("Destination"),
                            isActive: .constant(false),
                            label: { Text(item.title) })
                    }
                }

            }
            .actionSheet(isPresented: $addingItem)
            {
                ActionSheet(
                    title: Text("Add new child?"),
                    message: nil,
                    buttons:
                        [
                            .default(Text("Yes"))
                            {
                                AddChild()
                                addingItem = false
                            },
                            .cancel
                            {
                                addingItem = false
                            }

                        ])
            }
        }
    }
}

ParentObjectEntity并且ChildObjectEntity是 CoreData 托管对象:

@objc(ParentObjectEntity)
public class ParentObjectEntity: NSManagedObject {

var orderedChildren: [ChildObjectEntity] { children?.sorted{ $0.order < $1.order } ?? [] }

}

extension ParentObjectEntity {

    @NSManaged public var title_: String?
    @NSManaged public var children: Set<ChildObjectEntity>?

}
@objc(ChildObjectEntity)
public class ChildObjectEntity: NSManagedObject {

var title: String {
    get { title_ ?? "Unknown child" }
    set { title_ = newValue }
}

}

extension ChildObjectEntity {
    @NSManaged public var title_: String?
    @NSManaged public var order: Int16
    @NSManaged public var parent: ParentObjectEntity?

}

标签: core-dataswiftuiswiftui-listswiftui-navigationlinkswiftui-navigationview

解决方案


推荐阅读