如何在Swiftui中将函数的结果用作可绑定对象?

时间:2019-08-13 04:56:56

标签: swiftui

我正在使用Xcode 11 beta5开发一个简单的SwiftUI应用。 我有一个地方列表,我想显示该列表,然后添加/编辑它们。 数据来自核心数据。

我为此有3个课程: -CoreDataController,处理与核心数据的连接 -PlaceController,用于处理Places上的操作。

public class CoreDataController {

    static let instance = CoreDataController()
    private let container = NSPersistentContainer(name: "RememberV2")

    private init() {
        print("Start Init DataController")
        container.loadPersistentStores { (storeDescription, error) in
          if let error = error {
            fatalError("Failed to load store: \(error)")
          }
        }
        container.viewContext.automaticallyMergesChangesFromParent = true
        print("End Init DataController")
    }

    func getContext() -> NSManagedObjectContext {
        return container.viewContext
    }

    func save() {
        print("Start Save context")
        do{
            try container.viewContext.save()
        } catch {
            print("ERROR - saving context")
        }
        print("End Save context")
    }
}

public class PlaceController  {

    static let instance = PlaceController()

    private let dc = CoreDataController.instance
    private let entityName:String = "Place"


    private init() {
        print("Start init Place Controller")

        print("End init Place Controller")
    }

    func createPlace(name:String) -> Bool {
        let newPlace = NSEntityDescription.insertNewObject(forEntityName: entityName, into: dc.getContext())
        newPlace.setValue(UUID(), forKey: "id")
        newPlace.setValue(name, forKey: "name")
        dc.save()
        DataController.instance.places = getAllPlaces()
        return true
    }

    func createPlace(name:String, comment:String) -> Bool {
        print("Start - create place with comment")
        let newPlace = NSEntityDescription.insertNewObject(forEntityName: entityName, into: dc.getContext())
        newPlace.setValue(UUID(), forKey: "id")
        newPlace.setValue(name, forKey: "name")
        newPlace.setValue(comment, forKey: "comment")
        dc.save()
        print("End - create place with comment")
        DataController.instance.places = getAllPlaces()
        return true
    }


    func getAllPlaces() -> [Place] {
        let r = NSFetchRequest<NSFetchRequestResult>(entityName: entityName)
        if let fp = try? dc.getContext().fetch(r) as? [Place] {
            return fp
        }
        return [Place]()
    }

    func truncatePlaces() -> Bool {
        let r = NSFetchRequest<NSFetchRequestResult>(entityName: entityName)
        let batch = NSBatchDeleteRequest(fetchRequest: r)
        if (try? dc.getContext().execute(batch)) != nil {
            return true
        }
        return false
    }


}

在我看来,我只是使用以下功能:

List (pc.getAllPlaces(), id: \.id) { place in
            NavigationLink(destination: PlaceDetail(place: place)) {
                PlacesRow(place:place)
            }
        }

它可以显示信息,但是如果我添加一个新地点,则列表不会更新。 我必须返回主屏幕,然后再次显示“地方”屏幕以更新列表。

所以我使用另一个控制器:

class DataController: ObservableObject {

    @Published var places:[Place] = []

    static let instance = DataController()

    private init() {
        print("Start init Place Controller")

        print("End init Place Controller")
    }

}

在我看来,我只是显示ObservedObject的位置。

@ObservedObject var data: DataController = DataController.instance

然后在我的PlaceController中,我更新DataController中的表

DataController.instance.places = getAllPlaces()

那行得通,但是我有这个警告:

[TableView]仅警告一次:通知UITableView布置其可见单元格和其他内容,而不必放在视图层次结构中(表视图或其父视图之一尚未添加到窗口)。这可能会通过迫使表格视图中的视图加载和执行没有准确信息(例如表格视图范围,特征收集,布局边距,安全区域插图等)的布局而导致错误,并且还会由于多余的布局传递而导致不必要的性能开销

我也很确定有更好的方法来做到这一点...

你知道这是什么更好的方法吗?

谢谢, 尼古拉斯

0 个答案:

没有答案