Search code examples
imageswiftuiios-animations

Animation doesn't work on AnyTransition SwiftUI


I'm currently using SwiftUI on a function where a list of images change automatically with opacity animation for each image.

While I've currently managed to get a transition going, the opacity animation does not work no matter what I try.

Could someone please help me out with this...

The code I'm working on is as follows:

//
//  EpilogueThree.swift
//

import SwiftUI

struct EpilogueThree: View {
    let images = ["1", "2", "3"]
    let imageChangeTimer = Timer.publish(every: 3, on: .main, in: .common).autoconnect()
    let transition = AnyTransition.asymmetric(insertion: .slide, removal: .scale).combined(with: .opacity)
    @State private var imagePage = 2
    @State private var currentImageIndex = 0
    var body: some View {
        ZStack {
            VStack {
                Text("Page: \(imagePage)")
                    .font(.largeTitle)
                    .foregroundColor(.white)
                    .padding(.horizontal, 20)
                    .padding(.vertical, 5)
                    .background(.black.opacity(0.75))
                Image(images[currentImageIndex])
                    .resizable()
                    .ignoresSafeArea()
                    .transition(transition)
                    .onReceive(imageChangeTimer) { _ in
                        if imagePage > 0 {
                            self.currentImageIndex = (self.currentImageIndex + 1) % self.images.count
                            imagePage -= 1
                        }
                    }
            }
        }
    }
}

struct EpilogueThree_Previews: PreviewProvider {
    static var previews: some View {
        EpilogueThree()
            .previewInterfaceOrientation(.landscapeRight)
    }
}

The current code acts something like this: enter image description here

But the code I want needs to do something like this: enter image description here


Solution

  • We can make image removable in this case by add id (new id - new view) and add animation to container... for animation.

    Here is fixed part. Tested with Xcode 13.4 / iOS 15.5

    VStack {
    
    // .. other code
    
        Image(images[currentImageIndex])
            .resizable()
            .ignoresSafeArea()
            .id(imagePage)           // << here !!
            .transition(transition)
            .onReceive(imageChangeTimer) { _ in
                if imagePage > 0 {
                    self.currentImageIndex = (self.currentImageIndex + 1) % self.images.count
                    imagePage -= 1
                }
            }
    }
    .animation(.default, value: imagePage)  // << here !!