Comment animer le passage d'un texte à un autre avec Swift UI?

Dec 14 2020

J'ai un tableau de chaînes. Par exemple["Car", "Boat", "Van"]

Comment est-ce que j'anime le changement du texte dans le tableau (qui peut contenir plus de chaînes) afin qu'il passe de Carà Boatà Vanpar transition floue? Et pour qu'il boucle continuellement cela?

J'ai déjà une idée sur la façon d'animer, mais j'étais coincé dans le changement de texte. J'ai posé la question de savoir pourquoi le texte ne bascule pas ici -> Pourquoi la taille s'anime-t-elle et non le texte avec cette vue SwiftUI?

Mais j'ai pensé qu'il serait peut-être préférable d'écrire une question distincte sur la façon de changer le texte.

Réponses

2 davidev Dec 14 2020 at 07:57

Voici une solution possible pour animer du texte à partir d'un tableau. J'ai utilisé l'idée de transition Asperis à partir de cette solution ici

struct ContentView: View {
    var array = ["First", "Second", "Third"]
    @State var shortString = true
    
    @State var currentIndex : Int = 0
    @State var firstString : String = ""
    @State var secondString : String = ""

    var body: some View {

        VStack {
            if shortString {
               Text(firstString).font(.title).fixedSize()
               .transition(AnyTransition.opacity.animation(.easeInOut(duration:1.0)))
            }
            if !shortString {
                Text(secondString).font(.title).fixedSize()
                    .transition(AnyTransition.opacity.animation(.easeInOut(duration:1.0)))
            }
        }
        .animation(.default)
        .onAppear {
            firstString = array[0]
            secondString = array[1]
            
            let timer = Timer.scheduledTimer(withTimeInterval: 2.0, repeats: true) { _ in
                if (shortString) {
                    if currentIndex == array.count - 1 {
                        self.secondString = array[0]
                        currentIndex = 0
                    }
                    else {
                        self.secondString = array[currentIndex+1]
                        currentIndex += 1
                    }
                }
                else {
                    if currentIndex == array.count - 1 {
                        self.firstString = array[0]
                        currentIndex = 0
                    }
                    else {
                        self.firstString = array[currentIndex+1]
                        currentIndex += 1
                    }
                }
                shortString.toggle()
            }
        }
    }
}
Justacoder Dec 14 2020 at 09:02

J'ai déjà sélectionné la réponse @davidev. Mais sur la base de sa réponse, c'est ce que j'ai mis en œuvre. Vive 🍺

struct ContentView: View {
    var array = ["First", "Second", "Third"]
    @State var currentIndex : Int = 0
    @State var firstString : String = ""
    @State var timer: Timer? = nil
    @State var isBlurred = false
    
    var body: some View {
        VStack {
            Text(firstString).blur(radius: isBlurred ? 6 : 0)
        }.onAppear {
            self.timer = newTimer
        }
    }
    
    var newTimer: Timer {
        Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { v in
            let rndTime = [0.5, 0.3, 0.7, 1.0].randomElement()! // I wanted a random time up to 1 second.
            v.invalidate()
            currentIndex += 1
            if currentIndex == array.count { currentIndex = 0 }
            DispatchQueue.main.asyncAfter(deadline: .now() + rndTime) {
                self.isBlurred.toggle()
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
                    self.isBlurred.toggle()
                    firstString = array[currentIndex]
                    self.timer = newTimer
                }
            }
        }
    }
}