animation - 随着时间的推移动画矩形的宽度
问题描述
在 WatchOS 上的 SwiftUI 中,如何为 Rectangle (或任何视图)的宽度设置动画,使其从某个值开始并在指定的时间内动画到不同的值?
具体来说,我想为 Rectangle 设置动画以指示距离下一整分钟或一分钟后的下一个 30 秒的时间。
我看到的所有示例都是基于Timer.scheduledTimer
以相对较高的速度发射并设置@State
变量,但我的理解是,尤其是在 WatchOS 上应该避免这种情况。有没有更好的办法?
这是我拥有的基于计时器/状态的代码,但我觉得应该有一种更有效的方法:
import SwiftUI
func percentage() -> CGFloat {
1 - CGFloat(fmod(Date().timeIntervalSince1970, 30) / 30)
}
struct ContentView: View {
@State var ratio: CGFloat = percentage()
let timer = Timer.publish(every: 1 / 60, on:.main, in:.common).autoconnect()
var body: some View {
GeometryReader { geometry in
ZStack {
Rectangle()
.foregroundColor(Color.gray)
.frame(width:geometry.size.width, height:5)
HStack {
Rectangle()
.foregroundColor(Color.red)
.frame(width:geometry.size.width * self.ratio, height:5)
Spacer()
}
}
}.onReceive(self.timer) { _ in
self.ratio = percentage()
}
}
}
解决方案
我认为使用动画的“更有效的方式”:
struct AnimationRectangle: View {
struct AnimationRectangle: View {
@State private var percentage: CGFloat = 0.0
// count, how much time left to nearest 30 seconds
@State private var animationDuration = 30 - Double(fmod(Date().timeIntervalSince1970, 30))
private var repeatedAnimationFor30Seconds: Animation {
return Animation.easeInOut(duration: 30)
.repeatForever(autoreverses: false)
}
var body: some View {
VStack {
// just showing duration of current animation
Text("\(self.animationDuration)")
ZStack {
Rectangle()
.foregroundColor(.gray)
GeometryReader { geometry in
HStack {
Rectangle()
.foregroundColor(.green)
.frame(width: geometry.size.width * self.percentage)
Spacer()
}
}
}
.frame(height: 5)
.onAppear() {
// first animation without repeating
withAnimation(Animation.easeInOut(duration: self.animationDuration)) {
self.percentage = 1.0
}
// other repeated animations
DispatchQueue.main.asyncAfter(deadline: .now() + self.animationDuration) {
self.percentage = 0.0
self.animationDuration = 30.0
withAnimation(self.repeatedAnimationFor30Seconds) {
self.percentage = 1.0
}
}
}
}
}
}
struct AnimationRectangle_Previews: PreviewProvider {
static var previews: some View {
AnimationRectangle()
}
}
推荐阅读
- java - 如何从启动服务创建通知或 Toast?
- java - 通过 JSON (Spring Boot) 发送 java.lang.Boolean
- linux - Linux 内核构建编译错误 stringop-overflow 和 sizeof-pointer-memaccess
- php - 如何加入 Eloquent?
- python - Django UpdateView 错过查询集
- javascript - HTML 上的 Javascript 输入和输出
- php - 如何分组 GROUP_CONCAT()?
- php - 使用 Xpath 表达式并检查元素的计数
- java - 跨度未发送到 zipkin
- html - HTML href - 悬停不系统