如何使用 SwipeAction 动画删除列表中的项目?领域,斯威夫图伊

Fra*_*ois 7 realm swiftui

我试图在列表中向左滑动时以动画方式删除项目,但它不起作用。我正在使用 Realm 来保存任务。即使该操作包含在 withAnimation 中,也会立即应用删除,而无需动画。

我注意到,当我使用 onDelete 修改器时,动画播放得很好,但 swipeAction 没有动画

import SwiftUI
import RealmSwift

struct TasksView: View {
    
    @StateObject var tasksViewModel: TasksViewModel = TasksViewModel()
    
    var body: some View {
        
        List {
            if let tasks = tasksViewModel.tasks {
                ForEach(tasks.freeze(), id: \.id) { task in
                    Text(task.title)
                        .swipeActions(edge: .trailing, allowsFullSwipe: true) {
                            Button(role: .destructive) {
                                withAnimation {
                                    if let taskToDelete = task.thaw() {
                                        tasksViewModel.archive(taskToDelete)
                                    }
                                }
                            } label: {
                                Image("delete")
                            }
                            .tint(.red)
                        }
                }
            }
        }

    }
}

struct TasksViewNew_Previews: PreviewProvider {
    static var previews: some View {
        TasksView()
    }
}
Run Code Online (Sandbox Code Playgroud)
import Foundation
import RealmSwift

@MainActor
class TasksViewModel: ObservableObject {

    @Published var tasks: List<Task>?
    
    var token: NotificationToken?

    init() {
        let realm = try! Realm()
        let group = Group()
        do {
            try realm.write {
                let tasks = [Task(title: "TaskA"),
                             Task(title: "TaskB"),
                             Task(title: "TaskC"),
                             Task(title: "TaskD"),]
                realm.add(group)
                group.tasks.append(objectsIn: tasks)
                self.tasks = group.tasks
            }
        } catch {
            print("error")
        }
        
        token = group.observe({ (changes) in
              switch changes {
              case .error(_):
                  break
              case .change(_, _):
                  self.objectWillChange.send()
                  break
              case .deleted:
                  break
              }
              
          })
        
    }
    
    func archive(_ task: Task) {
        do {

            let realm = try Realm()
            try realm.write {
                realm.delete(task)
            }

        } catch {
            print(error)
        }
    }
    
}
Run Code Online (Sandbox Code Playgroud)
class Task: Object {
    @Persisted var id: String = UUID().uuidString
    @Persisted var title: String

    convenience init(title: String) {
        self.init()
        self.title = title
    }
}

class Group: Object, ObjectKeyIdentifiable {
    @Persisted var _id = ObjectId.generate()
    @Persisted var tasks = List<Task>()
}
Run Code Online (Sandbox Code Playgroud)

Max*_* Z. 3

作为我对原始问题的评论的后续内容,我在这里发布了我的代码,其中我遇到了使用动画触发删除的类似问题.swipeAction()。为了更好地进行比较,我的视图允许在自定义删除和使用.onDelete(). 结果显示了这样的差异:

在此输入图像描述

该代码基于 Paul Hudson 的示例,但他仅打印一条删除消息以表明该按钮已被点击。

// Friends.swift

import Foundation

class Friends: ObservableObject {
    @Published var list = ["Antoine", "Bas", "Curt", "Dave", "Erica"]
    
    func remove(friend: String) {
        if let index = list.firstIndex(of: friend) {
            list.remove(at: index)
        }
    }
    
    func remove(at indexSet: IndexSet) {
        list.remove(atOffsets: indexSet)
    }
}
Run Code Online (Sandbox Code Playgroud)
// ContentView.swift

import SwiftUI

struct ContentView: View {
    @EnvironmentObject var friends: Friends
    
    @State private var usingOnDelete = false
    
    var body: some View {
        List {
            Section {
                Toggle("Using onDelete", isOn: $usingOnDelete)
            }
            
            Section {
                if usingOnDelete {
                    listUsingOnDelete
                } else {
                    listNotUsingOnDelete
                }
            }
        }
        .navigationTitle("Deletion test")
    }
    
    private var listUsingOnDelete: some View {
        ForEach(friends.list, id: \.self) { friend in
            Text(friend)
        }
        .onDelete { friends.remove(at: $0) }
    }
    
    private var listNotUsingOnDelete: some View {
        ForEach(friends.list, id: \.self) { friend in
            Text(friend)
            .swipeActions(allowsFullSwipe: true) {
                Button(role: .destructive) {
                    withAnimation {
                        friends.remove(friend: friend)
                    }
                } label: {
                    Label("Delete", systemImage: "trash.fill")
                }
                
                Button {
                    print("Muting conversation")
                } label: {
                    Label("Mute", systemImage: "bell.slash.fill")
                }
                .tint(.indigo)
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        NavigationView {
            ContentView()
        }
        .environmentObject(Friends())
    }
}
Run Code Online (Sandbox Code Playgroud)
// MainApp.swift

import SwiftUI

@main
struct MainApp: App {
    @StateObject var friends = Friends()
    
    var body: some Scene {
        WindowGroup {
            NavigationView {
                ContentView()
            }
            .environmentObject(friends)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这个问题有解决办法吗?或者我们正在等待更新...:) (2认同)
  • 恐怕我还没有找到解决方案。 (2认同)