ios - SwiftUI 动画:如何延迟重复动画
问题描述
尝试在 SwiftUI 中实现以下动画并发现它完全不可能:
总结一下效果:一个重复的脉冲,以交错的延迟为每个片段设置动画。对于每个段:
- 从不透明度 = 0.5 开始,比例 = 1
- 动画到不透明度 = 1.0,比例 = 1.3
- 动画曲线以较长的缓出速度快速开始
此外,每个“脉冲”之间存在延迟。
我使用 SwiftUI 最接近的方法是使用.repeatForever
修改器连续重复动画。(下面的代码。暂时忽略时间上的不匹配。)
如何在动画的每个循环之间添加延迟?
下面是我的代码的结果:
import SwiftUI
struct ArrowShape : Shape {
func path(in rect: CGRect) -> Path {
var path = Path()
path.move(to: CGPoint(x: 0, y: 0))
path.addLine(to: CGPoint(x: rect.size.width, y: rect.size.height/2.0))
path.addLine(to: CGPoint(x: 0, y: rect.size.height))
return path
}
}
struct Arrows: View {
private let arrowCount = 3
@State var scale:CGFloat = 1.0
@State var fade:Double = 0.5
var body: some View {
ZStack {
Color(red: 29.0/255.0, green: 161.0/255.0, blue: 224.0/255.0).edgesIgnoringSafeArea(.all)
HStack{
ForEach(0..<self.arrowCount) { i in
ArrowShape()
.stroke(style: StrokeStyle(lineWidth: CGFloat(10),
lineCap: .round,
lineJoin: .round ))
.foregroundColor(Color.white)
.aspectRatio(CGSize(width: 28, height: 70), contentMode: .fit)
.frame(maxWidth: 20)
.animation(nil)
.opacity(self.fade)
.scaleEffect(self.scale)
.animation(
Animation.easeOut(duration: 0.8)
.repeatForever(autoreverses: true)
.delay(0.2 * Double(i))
)
}
}
.onAppear() {
self.scale = 1.2
self.fade = 1.0
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
Arrows()
}
}
解决方案
我认为您可以使用 Timer 和 DispatchQueue 来实现它,试试这个,看看它是否按您的意愿工作
struct Arrows: View {
private let arrowCount = 3
let timer = Timer.publish(every: 2, on: .main, in: .common).autoconnect()
@State var scale:CGFloat = 1.0
@State var fade:Double = 0.5
var body: some View {
ZStack {
Color(red: 29.0/255.0, green: 161.0/255.0, blue: 224.0/255.0).edgesIgnoringSafeArea(.all)
HStack{
ForEach(0..<self.arrowCount) { i in
ArrowShape()
.stroke(style: StrokeStyle(lineWidth: CGFloat(10),
lineCap: .round,
lineJoin: .round ))
.foregroundColor(Color.white)
.aspectRatio(CGSize(width: 28, height: 70), contentMode: .fit)
.frame(maxWidth: 20)
.animation(nil)
.opacity(self.fade)
.scaleEffect(self.scale)
.animation(
Animation.easeOut(duration: 0.5)
//.repeatForever(autoreverses: true)
.repeatCount(1, autoreverses: true)
.delay(0.2 * Double(i))
)
}.onReceive(self.timer) { _ in
self.scale = self.scale > 1 ? 1 : 1.2
self.fade = self.fade > 0.5 ? 0.5 : 1.0
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.scale = 1
self.fade = 0.5
}
}
}
}
}
}
推荐阅读
- web-scraping - casperjs 无法访问甚至 wget 可以访问的某些网站
- rust - 在 Rust 结果的 Iter 上调用 map
- python - 如何使用python在Firestore中查询包含对象数组的文档
- python - 当还有数字类型的列时,Pandas groupby sum 不包括 timedelta 类型的列
- python - 条形图和标签上的值
- c++ - 如果我采用 A = 10^9 和 B=10^9 ,则以下代码给出负输出。为什么?它为我提供了小整数的正确输出
- excel - 改变表格的格式
- git - 由于文件大,无法推送到 Github
- php - 变量作为 mailto 链接中的地址
- dm-script - 如何找到峰值位置(局部最大值)