带延迟的SwiftUI动画

带延迟的SwiftUI动画,swiftui,Swiftui,我有一个5个字母的数组,我需要显示每个字母从左到右一次滑动,每个字母之间间隔5秒,连续循环,但显示的字母不超过5个 这是我到目前为止所拥有的,但我被卡住了。这似乎不太难…我错过了什么?谢谢 import SwiftUI struct ContentView: View { @State private var letters = ["S","T","A","R","T&q

我有一个5个字母的数组,我需要显示每个字母从左到右一次滑动,每个字母之间间隔5秒,连续循环,但显示的字母不超过5个

这是我到目前为止所拥有的,但我被卡住了。这似乎不太难…我错过了什么?谢谢

import SwiftUI

struct ContentView: View {
            
    @State private var letters = ["S","T","A","R","T"]
    @State private var timer = Timer.publish(every: 5, tolerance: 0.5, on: .main, in: .common).autoconnect()
    
    var body: some View {
        ZStack {

            HStack {
                ForEach(self.letters, id:\.self) { letter in
                    Text(letter)
                        .font(.custom("Menlo", size: 18))
                        .fontWeight(.black)
                        .frame(width: 38, height: 38, alignment: .center)
                        .background(Color.red)
                        .clipShape(Circle())
                        .foregroundColor(.white)
                        .shadow(radius: 10, x: 10, y: 10)
                        .transition(AnyTransition.slide)
                        .animation(Animation.linear(duration: 1).repeatCount(1))
                }
            }
        }
        .onReceive(timer) {_ in
            //????? should I use this? where and how?
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

为了在屏幕上设置角色动画,首先需要将角色移出屏幕。这意味着您需要建立您的
ForEach
显示的字母数组

我让字母
可识别
给它们唯一的
id
s,这样就不会把
START
中的第一个
t
与第二个
t
混淆

我正在使用
偏移量
作为
动画
而不是
幻灯片
。字母的
到达
属性用于确定
偏移的方向


5个字符全部出现在屏幕上后会发生什么?他们应该一次离开一封吗?是的,当一封新信从左边进来时,他们应该从右边离开。
struct Letter: Identifiable {
    let letter: String
    var arriving: Bool
    let id = UUID()
}

struct ContentView: View {
    @State private var start = [" ","S","T","A","R","T"].map { Letter(letter: $0, arriving: true) }
    @State private var letters = [Letter]()
    @State private var timer = Timer.publish(every: 2, tolerance: 0.5, on: .main, in: .common).autoconnect()
    
    var body: some View {
        ZStack {

            HStack {
                ForEach(self.letters) { letter in
                    Text(letter.letter)
                        .font(.custom("Menlo", size: 18))
                        .fontWeight(.black)
                        .frame(width: 38, height: 38, alignment: .center)
                        .background(Color.red)
                        .clipShape(Circle())
                        .foregroundColor(.white)
                        .shadow(radius: 10, x: 10, y: 10)
                        .transition(AnyTransition.offset(x: letter.arriving ? -250 : 250))
                        .animation(Animation.linear(duration: 1).repeatCount(1))
                }
            }
        }
        .onReceive(timer) {_ in
            print("TIMER")
        
            var letter = start.removeLast()
            letter.arriving = true
            letters.indices.forEach { idx in letters[idx].arriving = false }
            letters = [letter] + letters
            if letters.count > 5 {
                let last = letters.removeLast()
                start = [last] + start
            }
        }
    }
}