Sliding new image in SwiftUI

Viewed 945

SWIFTUI - ANIMATED TRANSITIONS

I want to slide a new image from right to left when I click the next button and from left to right when I click the previous button. The sliding should be animated. Here is the code:

import SwiftUI

struct DetailView: View {
    @State private var image: Image?
    @State private var index: Int = 1
    
    var body: some View {
        VStack {
            image?
                .resizable()
                .scaledToFit()
                .transition(.slide)
                .animation(.default)
        }
        .onAppear(perform:loadImage)
        
        Button("Next", action: {
            index += 1
            loadImage()
        })
        
        Button("Previous", action: {
            index -= 1
            loadImage()
        })
    }
    
    
    func loadImage() {
        let strname = String(format: "image%02d", index)
        image = Image (strname)
    }
    
    struct DetailView_Previews: PreviewProvider {
        static var previews: some View {
            DetailView()
        }
    }
}
1 Answers

You can attach an id to the image so that SwiftUI sees 2 different images. This makes it animate the transition.

Edit: use the move transition to control direction.

struct DetailView: View {
    @State private var image: Image?
    @State private var index: Int = 1
    @State private var forwards = false

    var body: some View {
        VStack {
            image?
                .resizable()
                .scaledToFit()
                .transition(
                    .asymmetric(
                        insertion: .move(edge: forwards ? .trailing : .leading),
                        removal: .move(edge: forwards ? .leading : .trailing)
                    )
                )
                .animation(.default)
                .id(UUID())
        }
        .onAppear(perform:loadImage)

        Button("Next", action: {
            index += 1
            forwards = true
            loadImage()
        })

        Button("Previous", action: {
            index -= 1
            forwards = false
            loadImage()
        })
    }

    func loadImage() {
        let strname = String(format: "image%02d", index)
        image = Image(strname)
    }
}

Result:

Image slides in whenever it changes. If Next pressed, image slides in from right, otherwise, left.
Related