SwiftUI 如何使 CoreData 列表在 macOS 上可选择和可双击
Posted
技术标签:
【中文标题】SwiftUI 如何使 CoreData 列表在 macOS 上可选择和可双击【英文标题】:SwiftUI How to make CoreData list selectable and double clickable on macOS 【发布时间】:2020-12-09 18:11:54 【问题描述】:我有一个可选择和双击的名称列表。 我有一个 CoreData 记录列表,我无法选择或双击。
如何使 CoreData 列表可选择和双击?
这是我正在使用的可选列表代码:
import SwiftUI
struct ContentView: View
private static let values = ["Luke","Han","Chewie","Liea","R2D2"]
@State private var selection: String? = nil
var body: some View
VStack
HStack
List(Self.values, id: \.self, selection: $selection) name in
Text(name)
.gesture(TapGesture(count: 2).onEnded
print("double clicked")
selection = name
)
.simultaneousGesture(TapGesture().onEnded
print("single clicked")
selection = name
)
这是我的 ManagedObject:
@objc(Enquiry)
public class Enquiry: NSManagedObject
这是显示列表的 CoreData 列表:
import SwiftUI
import CoreData
struct EnquiryList: View
@Environment(\.managedObjectContext) private var viewContext
var enquiries: FetchRequest<Enquiry>
init (uuid: UUID)
enquiries = FetchRequest<Enquiry>(entity: Enquiry.entity(), sortDescriptors: [], predicate: NSPredicate(format: "UUID == %@", uuid as CVarArg))
@State private var selection: Enquiry? = nil
var body: some View
VStack
ForEach(enquiries, id: \.self, selection: $selection)
enquiry in
EnquiryListRow(enquiry: enquiry)
.gesture(TapGesture(count: 2).onEnded
print("double clicked")
selection = enquiry
)
ForEach 行给出以下错误:
我错过了什么?最终我想选择记录,然后双击打开一个带有查询的窗口。
根据 Asperi 的回答更改代码并没有让我更进一步:
List(enquiries.wrappedValue, id: \.self, selection: $selection)
enquiry in
Text("Hello")
enquiries.wrappedValue.count 显示有 3 条记录,但没有任何显示。将其移回 ForEach 将显示 Hello 三次。
【问题讨论】:
第二个例子不起作用?第一个对我来说很好 是的,这是我的问题。如何使第二个示例像第一个示例一样工作。 【参考方案1】:如果没有您丢失的代码,重现错误有点困难。不过,我已经编写了一些代码,您可以复制和粘贴这些代码以使工作正常进行。
请在下面找到我经过测试和工作的示例:
import SwiftUI
import Foundation
import CoreData
class PersistentContainer
public static var container: NSPersistentContainer =
let container = NSPersistentContainer(name: "DataModel")
container.loadPersistentStores(completionHandler: (storeDescription, error) in
if let error = error as NSError?
fatalError("Unresolved error \(error), \(error.userInfo)")
)
container.viewContext.automaticallyMergesChangesFromParent = true
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
return container
()
private init()
class DataModel: ObservableObject
private var _context: NSManagedObjectContext
@Published public var Enquiries: [Enquiry]
init()
self._context = PersistentContainer.container.viewContext
self.Enquiries = try! self._context.fetch(Enquiry.fetchRequest())
struct EnquiryListRow: View
public var Enquiry: Enquiry
var body: some View
Text("\(self.Enquiry.name ?? "(no name given)")")
struct ContentView: View
@StateObject var model = DataModel()
@State private var selection: Enquiry? = nil
var body: some View
List(self.model.Enquiries, id: \.self, selection: self.$selection) enquiry in
EnquiryListRow(Enquiry: enquiry)
.gesture(TapGesture(count: 2).onEnded
print("double clicked")
self.selection = enquiry
)
.simultaneousGesture(TapGesture().onEnded
print("single clicked")
self.selection = enquiry
)
struct ContentView_Previews: PreviewProvider
static var previews: some View
ContentView()
【讨论】:
【参考方案2】:您也应该在第二种情况下使用 List - ForEach
只是一个没有 selection
功能的动态组:
var body: some View
VStack
List(selection: $selection) // << here !!
ForEach(enquiries, id: \.self)
enquiry in
EnquiryListRow(enquiry: enquiry)
.gesture(TapGesture(count: 2).onEnded
print("double clicked")
selection = enquiry
)
【讨论】:
如果我做出改变,我会得到 Initializer 'init(_:id:selection:rowContent:)' 要求 'FetchRequest以上是关于SwiftUI 如何使 CoreData 列表在 macOS 上可选择和可双击的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI - 如何在 CoreData 中删除实体中的行
SwiftUI 2.0列表项层级缩进显示CoreData托管数据的3种实现
SwiftUI 2.0列表项层级缩进显示CoreData托管数据的3种实现