SwiftUI 和 CoreData:删除列表项和前导标签

问题描述 投票:0回答:1

我的

SidebarView
中有一个
NavigationSplitView
SidebarView
是具有领先标签的用户列表。

当我尝试从该列表中滑动删除用户时,我的

SideBarLabel
视图中会抛出错误:
Fatal error: Unexpectedly found nil while unwrapping an Optional value
。 看起来用户被删除后标签仍然存在。如何从 CoreData 中删除包括标签和用户对象的完整行? 我使用这个删除功能,但不知道如何删除用户标签:

我的删除功能在

SidebarView

private func deleteSelectedUser(_ user: User){
    print(user)
  withAnimation {
          moc.delete(user)
      }
      
      do {
          try moc.save()

      } catch {
          let nsError = error as NSError
          fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
      }
}

我的

SidebarView
创建列表和滑动功能的代码:

import SwiftUI
import CoreData

struct SidebarView: View {

@Environment(\.managedObjectContext) var moc
@FetchRequest(sortDescriptors: [SortDescriptor(\.name)])
var users: FetchedResults<User>

@Binding var selection: User.ID?

var body: some View {
    List(selection: $selection) {
        Text("Anwender")
            .font(.headline)
            .multilineTextAlignment(.leading)
         
        ForEach(users) { user in
            SidebarLabel(user: user)
                .swipeActions { Button(role: .destructive, action: {
                  deleteSelectedUser(user)
                    //print("swiped item is: \(user.name!)")
                }) {
                  Label("Remove User", systemImage: "trash")
                } }
...

我在列表中创建标签和用户:

import SwiftUI

struct SidebarLabel: View {

   //@Environment(\.managedObjectContext) var moc

   @ObservedObject var user: User

   var body: some View {
       Label(user.name!, systemImage: "person.circle")
   }
}
macos swiftui core-data delete-row
1个回答
0
投票

您遇到此问题的原因是您的

delete
命令在
withAnimation
块内异步发生,这不会阻止该方法的其余部分。因此,当代码点击
try moc.save()
时,该对象可能尚未真正被删除。然后它会从上下文中删除并且不会保存(直到您下次调用
save()
) - 因此它可能仍会出现在获取的结果中,但任何访问它的尝试都将失败。

您可以将动画添加到

withAnimation
中,而不是将保存放在
@FetchRequest
块中,以便您的删除方法更清晰:

struct SidebarView: View {
  // ...
  @FetchRequest(
    sortDescriptors: [SortDescriptor(\.name)],
    animation: .default
  ) var users: FetchedResults<User>
  // ...etc...

  private func deleteSelectedUser(_ user: User){
    do {
      moc.delete(user)
      try moc.save()
    } catch {
      let nsError = error as NSError
      fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
    }
  }
}

如果您仍然发现错误,您可以通过检查用户是否已在您的

SidebarLabel
中删除来获得额外的安全性:

struct SidebarLabel: View {
  @ObservedObject var user: User

  var body: some View {
    if !user.isDeleted {
      Label(user.name!, systemImage: "person.circle")
    }
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.