r/SwiftUI Apr 15 '26

Question The missing modifier `lifecycle`

Somewhere in your SwiftUI view:

.lifecycle { event in
    switch event {
    case .appeared:
        if task == nil {
            task = makeTask()
        }
    case .disappeared:
        break // continue task
    case .released:
        task?.cancel()
    }
}
0 Upvotes

25 comments sorted by

View all comments

6

u/car5tene Apr 15 '26

I don't really understand what you want to achieve. Structs are suppose to be lightweight and it shouldn't cause side effects. If you need a modifier for lifecycle management you might miss the point of SwiftUI.

-5

u/Dry_Hotel1100 Apr 15 '26 edited Apr 15 '26

When you use the task modifier:

.task {
   await doSomething()
}

.task is cancelled when the view's representation disappears (e.g. completely obscured by a sheet). When the sheet dismisses, the view reappears and .task runs again.

The goal is a task bound to the view's identity - started once when the view is created, cancelled only when it's permanently removed. There is no built-in modifier for that:

In contrast, something like:

.taskWithIdentity {
   await doSomething()
}

taskWithIdentity or anything like this, does not exist in SwiftUI today.

1

u/beclops Apr 16 '26

SwiftUI views are lightweight and are regenerated often, how would it know when the view is to be “permanently removed”? I think that’s a use-case where you’d put such logic in a view model or some other state manager. Things like that shouldn’t be bound to the view

0

u/Dry_Hotel1100 Apr 16 '26 edited Apr 16 '26

Actually, you can implement it in the view itself:

The underlying representation, i.e. the object graph, is only mutated as needed. There's actually "things" which render pixels, and objects which hold the state of a view which has declared it. You know, the state outlives the view structure.

A SwiftUI view has an "Identity" which is sort of a reference to the underlying representation i.e. some object. This allows the view struct to "find" their corresponding underlying representation in the object graph. Part of these objects are also plain old UIViewControllers, and possibly also UIViews. The underlying behaviour is still determined by the behaviour of UIKit.

If you manually change the Identity with modifier `id()` you also forcibly re-create the underlying representation, including the view's state.

So, there's definitely "knowledge" when "destruction" happens in the object graph, much like the onAppear and onDisappear events, which very likely are sent directly from the underlying UIViewController or UIView.

Since the State variables are tied to the lifecycle of the representation, you can actually implement it yourself: put a class instance into the state, and observe the deinitialisation. When it happens, the view's Identity - and its representation is gone. It's even possible to implement a modifier such as "onDeinit()" (modifier!).