gpt4 book ai didi

core-data - SwiftUI重新排序列表中的CoreData对象

转载 作者:行者123 更新时间:2023-12-03 13:44:00 25 4
gpt4 key购买 nike

我想更改从核心数据中检索对象的列表中行的顺序。移动行是可行的,但是问题是我无法保存更改。我不知道如何保存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())
}
}


谢谢你的帮助。

最佳答案

注意:尽管我在示例项目中使用了并行逻辑,但该项目似乎正在运行,但以下答案未经测试。

答案有两个部分。正如Joakim Danielson所说,要保留用户的首选订单,您需要将订单保存在CoreItem类中。修改后的类如下所示:

public class CoreItem: NSManagedObject, Identifiable{
@NSManaged public var name: String
@NSManaged public var userOrder: Int16
}

第二部分是根据 userOrder属性对项目进行排序。在初始化时, userOrder通常默认为零,因此在 name中按 userOrder进行排序可能很有用。假设您要执行此操作,然后在CoreItemList代码中:
@FetchRequest( entity: CoreItem.entity(),
sortDescriptors:
[
NSSortDescriptor(
keyPath: \CoreItem.userOrder,
ascending: true),
NSSortDescriptor(
keyPath:\CoreItem.name,
ascending: true )
]
) var coreItems: FetchedResults<CoreItem>

第三部分是您需要告诉swiftui允许用户修改列表的顺序。如您的示例所示,这是使用 onMove修饰符完成的。在该修饰符中,您将执行所需的操作,以按照用户的首选顺序对列表进行重新排序。例如,您可以调用一个名为 move的便利函数,以便该修饰符显示为:
.onMove( perform: move )

您的 move函数将被传递给IndexSet和Int。索引集包含FetchRequestResult中所有要移动的项目(通常只是一个项目)。 Int指示应将其移动到的位置。逻辑将是:
private func move( from source: IndexSet, to destination: Int) 
{
// Make an array of items from fetched results
var revisedItems: [ CoreItem ] = coreItems.map{ $0 }

// change the order of the items in the array
revisedItems.move(fromOffsets: source, toOffset: destination )

// update the userOrder attribute in revisedItems to
// persist the new order. This is done in reverse order
// to minimize changes to the indices.
for reverseIndex in stride( from: revisedItems.count - 1,
through: 0,
by: -1 )
{
revisedItems[ reverseIndex ].userOrder =
Int16( reverseIndex )
}
}

技术提醒:removedItems中存储的项目是类(即通过引用),因此更新这些项目将必然会更新所获取结果中的项目。 @FetchedResults包装器将使您的用户界面反射(reflect)新的顺序。

诚然,我是SwiftUI的新手。可能会有一个更优雅的解决方案!

保罗· hudson (Paul Hudson)(《与黑客共舞》)有更多细节。这是 link,用于获取列表中移动数据的信息。这是用于在SwiftUI中使用核心数据的 link(它涉及删除列表中的项目,但与 onMove逻辑极为相似)

关于core-data - SwiftUI重新排序列表中的CoreData对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59742218/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com