【问题标题】:SwiftUI dismiss after list reorder列表重新排序后 SwiftUI 关闭
【发布时间】:2021-10-14 18:08:24
【问题描述】:

我正在尝试重新排序我的 CoreData 项目,但是当我尝试重新排序项目并放置单元格时,我的列表视图被关闭。所有更改都会保存并正确显示在其他视图和修改的列表中。 这是我的代码

import SwiftUI

struct DaysOrderView: View {
    
    @Environment(\.managedObjectContext) var moc
    @FetchRequest(entity: Days.entity(), sortDescriptors:[NSSortDescriptor(key: "id", ascending: true)]) var days : FetchedResults<Days>
    
    var body: some View {
        List {
            ForEach(days, id: \.self ) { day in
                HStack {
                    Image(systemName: day.isDisplayed.boolValue ? "checkmark.circle.fill" : "checkmark.circle").foregroundColor(.yellow)
                    Text(day.name)
                }
            }
            .onMove(perform: onMove)
        }
            .toolbar {
                EditButton()
            }
    }
    
    private func onMove(source: IndexSet, destination: Int) {
            
        var revisedItems: [ Days ] = days.map{ $0 }
        
            revisedItems.move(fromOffsets: source, toOffset: destination )
        
            for reverseIndex in stride( from: revisedItems.count - 1,
                                        through: 0,
                                        by: -1 )
            {
                    revisedItems[ reverseIndex ].id = Int16( reverseIndex )
            }
    }
}

【问题讨论】:

  • 欢迎来到 Stack Overflow!您是否希望有一些任意的排序顺序?
  • 是的,我希望它按 id 排序。

标签: swift list swiftui


【解决方案1】:

id 不是任意的,更改 id 以更改排序顺序可能会产生后果。如果您想要一个可更改的顺序,我建议您使用专用于排序顺序的属性来跟踪它并更改它。

我使用sortOrder 属性和id 属性组合了一个快速应用程序。当我使用 'idas anInt16` 并对其进行排序和更改时,出现以下错误:

ForEach>: ID 2 在集合中出现多次,这将给出 未定义的结果!

将其换成sortOrder 属性没有出现错误。由于您没有使用 Core Data 发布整个代码,这是可以理解的,因此我不能 100% 确定,但我敢打赌您的问题归结为这个问题。此外,您应该将您的 id 设为 UUID(),这就是它存在的目的,并且不要更改 id。这就像有多个孩子的父母每天交换孩子的名字一样。它可能有效,但很可能是混乱。

FWIW 用于测试的代码:

struct ContentView: View {
    @Environment(\.managedObjectContext) private var viewContext

    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \Item.sortOrder, ascending: true)],
        animation: .default)
    private var items: FetchedResults<Item>

    var body: some View {
        NavigationView {
            List {
                ForEach(items) { item in
                    NavigationLink {
                        Text("Item \(item.sortOrder) at \(item.timestamp!, formatter: itemFormatter)")
                    } label: {
                        Text(item.timestamp!, formatter: itemFormatter)
                    }
                }
                .onDelete(perform: deleteItems)
                .onMove(perform: onMove)
            }
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    EditButton()
                }
                ToolbarItem {
                    Button(action: addItem) {
                        Label("Add Item", systemImage: "plus")
                    }
                }
            }
            Text("Select an item")
        }
    }

    private func addItem() {
        withAnimation {
            let newItem = Item(context: viewContext)
            newItem.timestamp = Date()
            newItem.id = UUID()
            newItem.sortOrder = Int16(items.count)

            do {
                try viewContext.save()
            } catch {
                // Replace this implementation with code to handle the error appropriately.
                // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
                let nsError = error as NSError
                fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
            }
        }
    }

    private func deleteItems(offsets: IndexSet) {
        withAnimation {
            offsets.map { items[$0] }.forEach(viewContext.delete)

            do {
                try viewContext.save()
            } catch {
                // Replace this implementation with code to handle the error appropriately.
                // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
                let nsError = error as NSError
                fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
            }
        }
    }
    
    private func onMove(source: IndexSet, destination: Int) {
            
        var revisedItems: [ Item ] = items.map{ $0 }
        
            revisedItems.move(fromOffsets: source, toOffset: destination )
        
            for reverseIndex in stride( from: revisedItems.count - 1,
                                        through: 0,
                                        by: -1 )
            {
                    revisedItems[ reverseIndex ].sortOrder = Int16( reverseIndex )
            }
    }

}

这是我添加属性的基本“使用核心数据”代码。

【讨论】:

  • 不幸的是,这并没有解决问题。重新排序后视图仍然关闭:/
猜你喜欢
  • 2022-07-01
  • 1970-01-01
  • 2011-01-11
  • 2015-09-16
  • 1970-01-01
  • 2011-07-06
  • 2020-09-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多