为什么删除索引后,SwiftUI会对列表项进行不同的动画设置?

问题描述

我真的很难理解为什么会发生这种情况,我很茫然。

这种情况似乎是动画的不同,这取决于动画项目占用的数组的索引处是否存在某个项目。

这是我正在使用的代码

  @FetchRequest(
    sortDescriptors: [NSSortDescriptor(keyPath: \Profile.lastUsed,ascending: true)],animation: .spring()
  )
  private var profiles: FetchedResults<Profile>

  var body: some View {
    List() {
      ForEach(profiles,id: \.id) { profile in
        ProfileView(profile)
      }
    }
    .listStyle(InsetListStyle())
    .toolbar {
      Button(action: addItem) {
        Label("Add Item",systemImage: "plus")
      }
      Button(action: deleteItem) {
        Label("Remove Items",systemImage: "minus")
      }
    }
  }
  
  private func addItem() {
      let profile = Profile(context: viewContext)
      profile.id = UUID()
      profile.lastUsed = Date()
      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 deleteItem() {
    if profiles.last != nil { viewContext.delete(profiles.last!) }
    
    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)")
    }
  }

struct ProfileView: View {
  @State var isPopover = false
  var profile: Profile;
  
  init(_ profile: Profile) {
    self.profile = profile;
  }
  
  var body: some View {
    Button(action: { self.isPopover.toggle() }) {
      ZStack(alignment: .leading) {
        RoundedRectangle(cornerRadius: 5,style: .continuous)
          .fill(Color(NSColor.separatorColor).opacity(0.75))
        vstack(alignment: .leading) {
          Text("\(profile.id!)").font(.headline)
          Text("Profile last used \(profile.lastUsed!,formatter: itemFormatter)").font(.body)
        }.padding(12)
      }
    }
    .buttonStyle(PlainButtonStyle())
    .padding(.bottom,8)
    .popover(isPresented: self.$isPopover,arrowEdge: .trailing) {
       PopoverView()
    }
  }
}

结果可以看到here

我不确定我是否在这里丢失了一些信息,或者它是否是一个错误,例如Big Sur Beta 4。

解决方法

尝试以下操作...

  var body: some View {
    Button(action: { self.isPopover.toggle() }) {
      ZStack(alignment: .leading) {
        RoundedRectangle(cornerRadius: 5,style: .continuous)
          .fill(Color(NSColor.separatorColor).opacity(0.75))
        VStack(alignment: .leading) {
          Text("\(profile.id!)").font(.headline)
          Text("Profile last used \(profile.lastUsed!,formatter: itemFormatter)").font(.body)
        }.padding(12)
      }
    }
    .buttonStyle(PlainButtonStyle())
    .padding(.bottom,8)
    .animation(nil)          // << here !!
...