TaskModifier.swift 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. extension View {
  2. /// Starts a task before a view appears (but after ``View/body`` has been
  3. /// accessed), and cancels the task when the view disappears. Additionally,
  4. /// if `id` changes the current task is cancelled and a new one is started.
  5. ///
  6. /// This variant of `task` can be useful when the lifetime of the task
  7. /// must be linked to a value with a potentially shorter lifetime than the
  8. /// view.
  9. ///
  10. /// - Parameters:
  11. /// - id: The ID of the task.
  12. /// - priority: The priority of the task.
  13. /// - action: The action to perform within the task.
  14. public nonisolated func task<Id: Equatable>(
  15. id: Id,
  16. priority: TaskPriority = .userInitiated,
  17. _ action: @escaping () async -> Void
  18. ) -> some View {
  19. TaskModifier(
  20. id: id,
  21. content: TupleView1(self),
  22. priority: priority,
  23. action: action
  24. )
  25. }
  26. /// Starts a task before a view appears (but after ``View/body`` has been
  27. /// accessed), and cancels the task when the view disappears.
  28. ///
  29. /// - Parameters:
  30. /// - priority: The priority of the task.
  31. /// - action: The action to perform within the task.
  32. public nonisolated func task(
  33. priority: TaskPriority = .userInitiated,
  34. _ action: @escaping () async -> Void
  35. ) -> some View {
  36. TaskModifier(
  37. id: 0,
  38. content: TupleView1(self),
  39. priority: priority,
  40. action: action
  41. )
  42. }
  43. }
  44. struct TaskModifier<Id: Equatable, Content: View> {
  45. @State var task: Task<(), any Error>? = nil
  46. var id: Id
  47. var content: Content
  48. var priority: TaskPriority
  49. var action: () async -> Void
  50. }
  51. extension TaskModifier: View {
  52. var body: some View {
  53. content.onChange(of: id, initial: true) {
  54. task?.cancel()
  55. task = Task(priority: priority) {
  56. await action()
  57. }
  58. }.onDisappear {
  59. task?.cancel()
  60. }
  61. }
  62. }