【发布时间】:2020-05-01 16:15:20
【问题描述】:
我想更改从核心数据中检索对象的列表中的行顺序。移动行有效,但问题是我无法保存更改。我不知道如何保存 CoreData 对象的更改索引。
这是我的代码:
核心数据类:
public class CoreItem: NSManagedObject, Identifiable{
@NSManaged public var name: String
}
extension CoreItem{
static func getAllCoreItems() -> NSFetchRequest <CoreItem> {
let request: NSFetchRequest<CoreItem> = CoreItem.fetchRequest() as! NSFetchRequest<CoreItem>
let sortDescriptor = NSSortDescriptor(key: "date", ascending: true)
request.sortDescriptors = [sortDescriptor]
return request
}
}
extension Collection where Element == CoreItem, Index == Int {
func move(set: IndexSet, to: Int, from managedObjectContext: NSManagedObjectContext) {
do {
try managedObjectContext.save()
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
列表:
struct CoreItemList: View {
@Environment(\.managedObjectContext) var managedObjectContext
@FetchRequest(fetchRequest: CoreItem.getAllCoreItems()) var CoreItems: FetchedResults<CoreItem>
var body: some View {
NavigationView{
List {
ForEach(CoreItems, id: \.self){
coreItem in
CoreItemRow(coreItem: coreItem)
}.onDelete {
IndexSet in let deleteItem = self.CoreItems[IndexSet.first!]
self.managedObjectContext.delete(deleteItem)
do {
try self.managedObjectContext.save()
} catch {
print(error)
}
}
.onMove {
self.CoreItems.move(set: $0, to: $1, from: self.managedObjectContext)
}
}
.navigationBarItems(trailing: EditButton())
}.navigationViewStyle(StackNavigationViewStyle())
}
}
感谢您的帮助。
【问题讨论】:
-
如果您想存储订单,那么您需要在 CoreItem 实体中为其提供一个属性,并且您需要在排序描述符中使用该属性。但这真的是个好主意吗,您需要为所有受移动影响的对象更新此属性吗?
-
也许有更好的解决方案,我不知道。问题是我想让用户重新排序列表并保存更改。
-
就像我说的,那么你需要一个包含订单的属性
-
我见过的一种模式可以避免 Joakim 提到的缩放问题,即在移动单个项目时必须更新许多项目,是让 iterm 上的排序标准是某种小数.然后,当一个项目被移动时,通过将其 order 值设置为列表中它前面和后面的项目之间的值来更新单个项目。
-
您可以根据浮动序列进行排序。当您在最后添加元素时,您会增加 1。当您在两个之间插入时,您会找到它们的平均值。最终你会达到浮动的分辨率。这将需要发生如此多的划分,您可以使用它来触发非常昂贵的 - 数组重新排序和将元素间隔 1。