[Doc Request]: animation
smiLLe opened this issue · comments
Checklist
- Reviewed the README and documentation.
- Confirmed that this is uncovered by existing docs or examples.
- Checked existing issues & PRs to ensure not duplicated.
Description
This is not exactly a documentation request or a feature request. More a question.
Previously when I had a .task {}
I could do something like this:
@State private var asyncData: Data = .loading
var body: some View {
Group {
switch asyncData {
case .success:
case .loading:
case .failure:
}
}
.task {
withAnimation {
asyncData = .loading
}
let data = await fetch()
withAnimation {
asyncData = .data
}
}
}
And it had great animations by changing the content from loading > success and so on.
It no longer animates when I use Suspense
because there is no withAnimation
involved when I use
@Watch(DataAtom()) private var dataTask
.
Do you have a suggestion or an idea on how I can achieve the "old" behaviour?
Motivation & Context
No response
View.animation
modifier would work for you!
@Watch(DataAtom())
private var dataTask
var body: some View {
Group {
switch asyncData {
case .success:
case .loading:
case .failure:
}
}
.animation(.default, value: dataTask.value)
}
The Atom is a ThrowingTaskAtom
and my code looks like this
@Watch(DataAtom())
private var dataTask
var body: some View {
List {
Section {
Suspense(dataTask) {
}
suspending: {}
failure: {}
}
.animation( ... )
}
}
It is not possible to add the .animation()
mod and use the dataTask or its phase because the Phase Failure is an any Error
and does not conform to Equatable
. I guess I have no option but to rewrite the ThrowingTaskAtom
to be a TaskAtom
I will close as this is just not possible to implement using ThrowingTaskAtom
. It is working for TaskAtom
and the animation()
has to be used on the List List {}.animation()
My bad, my example code lacked some important points I wanted to suggest.
You might want to try using phase modifier to handle the async value as an enum representation so you can set phase.value
as animation
's value argument.
// DataAtom is a ThrowingTaskAtom
@Watch(DataAtom().phase)
private var dataPhase: AsyncPhase<Data, Error>
var body: some View {
Group {
switch dataPhase {
case .suspending: ...
case .success(let value): ...
case .failure(let error): ...
}
}
.animation(.default, value: dataPhase.value)
}
@ra1028 Ohhh, I was trying to use phase but not its .value
which is working :) Thanks for the help
Which made me think of, why do we need the Suspense View when we could just use phase with switch cases?
Suspense is for those who want to handle Task instance directly, but yes, phase
is more convenient in most cases :)