我有一个由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()
}
}
答案 0 :(得分:0)
为了使角色在屏幕上动起来,需要先将它们移出屏幕。这意味着您需要建立ForEach
显示的字母数组。
我将字母Identifiable
赋予了它们唯一的id
,以便不会将T
中的第一个START
与第二个T
混淆。
我为offset
使用了animation
而不是slide
。字母的arriving
属性用于确定offset
的方向。
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
}
}
}
}