Reputation: 5495
I have two images, ImageA
and ImageB
, and my goal is to animate a transition between them in the following manner:
ImageA
is loadedImageA
transitions to ImageB
, with a duration of 1.5 secondsWith regular Swift, it would be using an UIView.animate
closure with an animation duration and a pause.
Here is my attempt with SwiftUI, which is not showing a smooth transition, but a hard image change instead:
VStack(alignment: .leading, spacing: 0) {
Image(images.randomElement()!)
.resizable()
.scaledToFill()
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
withAnimation() { //added
self.shouldTransition.toggle()
}
}
if shouldTransition {
Image(images.randomElement()!)
.resizable()
.animation(.easeInOut(duration: 1.5))
.scaledToFill()
}
}
What is missing in my implementation to animate the image transition?
Edit: the entire codebase can be found here: TestWidget Github
Upvotes: 5
Views: 4873
Reputation: 257533
You don't specify which kind of transition do you want, by default SwiftUI uses opacity...
Try the following
VStack(alignment: .leading, spacing: 0) {
if !shouldTransition {
Image(images.randomElement()!)
.resizable()
.scaledToFill()
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
self.shouldTransition.toggle()
}
}
//.transition(.move(edge: .top)) // uncomment to modify transition
}
if shouldTransition {
Image(images.randomElement()!)
.resizable()
.scaledToFill()
//.transition(.move(edge: .top)) // uncomment to modify transition
}
}.animation(.easeInOut(duration: 1.5), value: shouldTransition)
Upvotes: 3
Reputation: 66
You have to add withAnimation() { ... }
wrapper around observed changes, which you want to be animated.
Change your code to
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
withAnimation(){
self.shouldTransition.toggle()
}
}
Upvotes: 1