path - AnimatableData 在 SwiftUI 的 Shape 对象中不起作用
问题描述
我有这个我正在尝试制作动画的 Shape 对象(曲线):
private struct Curve : Shape {
private var startAngle : CGFloat
private var endAngle : CGFloat
private var drawn : Bool
private var hAdjustment : CGFloat
var clockwise : Bool = true
init(side: CurveSide, isDrawn: Bool) {
self.startAngle = side.startAngle
self.endAngle = side.endAngle
self.hAdjustment = side == .left ? 25 : -25
self.drawn = isDrawn
}
var animatableData : CGFloat {
get { self.endAngle }
set { self.endAngle = newValue }
}
func path(in rect: CGRect) -> Path {
let rotationAdjusment = CGFloat(90.0)
var baseCirclePath = Path()
baseCirclePath.addArc(center: CGPoint(x: rect.midX + CGFloat(self.hAdjustment), y: rect.midY),
radius: rect.width / 2.3,
startAngle: self.drawn ? Angle(degrees: Double(self.startAngle - rotationAdjusment)) : Angle(degrees: 0),
endAngle: self.drawn ? Angle(degrees: Double(self.endAngle - rotationAdjusment)) : Angle(degrees: 0),
clockwise: !self.clockwise)
return baseCirclePath
}
}
这是我尝试使用该形状(曲线)的 contentView:
HStack {
Spacer()
Curve(side: CurveSide.left, isDrawn: self.leftCurveDrawn)
.stroke(Color.white, lineWidth: 2)
.frame(width: 100)
Curve(side: CurveSide.right, isDrawn: self.rightCurveDrawn)
.stroke(Color.white, lineWidth: 2)
.frame(width:100)
Spacer()
}
我正在使用这些变量来触发动画:
@State private var rightCurveDrawn = true
@State private var leftCurveDrawn = true
这就是我在屏幕上看到的。问题是每次我切换@State 变量时,曲线只会出现和消失而没有动画。先感谢您。
解决方案
看起来您必须自己实现动画值。多么有趣!
为了让你开始,你可以在你的形状中添加这样的东西:
private var multiplier = 1.0
var animatableData: CGFloat {
get { CGFloat(self.multiplier) }
set { self.multiplier = Double(newValue) }
}
multiplier
没什么特别的,这是我们开发人员增加的价值。animatableData
然而,这就是 SwiftUI 的魔力。通过将您的状态更改包装在一个withAnimation
闭包中,它会立即将您的形状设置为新值,评估 animatableData 的最终结果,然后在整个动画时间内插入这些值。
我们可以像这样使用 animatableData 中的乘数集:
baseCirclePath.addArc(center: CGPoint(x: rect.midX + CGFloat(self.hAdjustment), y: rect.midY),
radius: rect.width / 2.3,
startAngle: Angle(degrees: Double(self.startAngle - rotationAdjusment) * self.multiplier),
endAngle: Angle(degrees: Double(self.endAngle - rotationAdjusment) * self.multiplier),
clockwise: !self.clockwise)
并且不要忘记将其添加到您的 init 语句的末尾,以便为 SwiftUI 提供一些评估:
self.multiplier = self.drawn ? 1 : 0
笔记
请注意,我的简单实现animatableData
可能不是您想要的那种动画,但您可以根据需要自定义它。
最后,在这里我学到了关于这个特定问题的所有信息。
推荐阅读
- javascript - 三路比较变量和字符串
- java - JavaFX - 如何关闭选项卡
- c# - linq 使用 LINQ 合并 2 列表对象列表
- python - 要插入数据框的选定行-pandas
- laravel - Laravel:更新数据库的更好方法(一个班轮)?
- ios - 使用 DispatchGroup 在两个不同的类之间进行通信?
- android - 无法通过 Firebase 存储更新 ImageView
- node.js - Azure Web App Bot - 在 OAuth 完成后触发事件
- java - 13个相邻数的最大和
- python - 如何在 vs 代码中禁用 pylint 未使用的导入错误消息