SwiftUI-使用不同曲线设置多个参数的动画
我正在SwiftUISwiftUI-使用不同曲线设置多个参数的动画,swiftui,Swiftui,我正在SwiftUI视图中探索正弦波渲染,并已将我的视图构建为具有3个可控参数: 阶段(控制偏移并允许“水平”设置动画) 振幅(控制每个峰值的高度) 频率(有多少完整波) 以下是一个屏幕截图: 我的正弦波被实现为形状,因此它已经是可动画的。我制作了振幅和频率一对AnimatablePair并将其作为我的形状的可设置动画的数据公开如下: var animatableData: AnimatablePair<CGFloat, CGFloat> { get { .init(f
视图中探索正弦波渲染,并已将我的视图构建为具有3个可控参数:
阶段
(控制偏移并允许“水平”设置动画)
振幅
(控制每个峰值的高度)
频率
(有多少完整波)
以下是一个屏幕截图:
我的正弦波
被实现为形状
,因此它已经是可动画的
。我制作了振幅
和频率
一对AnimatablePair
并将其作为我的形状的可设置动画的
数据公开如下:
var animatableData: AnimatablePair<CGFloat, CGFloat> {
get { .init(frequency, amplitude) }
set {
frequency = newValue.first
amplitude = newValue.second
}
}
现在我还想给阶段设置动画。但我不想让这辆车自动倒车,我希望它能快得多。不幸的是,在这个块旁边添加另一个带有动画的块没有效果,即使我将它作为可设置动画的数据的一部分。最后一个动画块始终获胜
我应该如何处理希望使用两个不同的动画
实例为两个属性设置动画的问题?以下是可能的方法(scratchy)。假设您将可设置动画的一对组合到结构中,并将其作为单个值使用,则可以使用.animation(\uu,value:)
为每个值指定专用动画:
@State private var pair: CGSize = .zero
@State private var phase: CGFloat = .zero
...
SineWaveShape(phase: phase, amplitude: amplitude, frequency: frequency)
.stroke(style: StrokeStyle(lineWidth: 3, lineCap: .round, lineJoin: .round))
.foregroundColor(.red)
.animation(Animation.linear(duration: 5).repeatForever(), value: phase)
.animation(Animation.spring(response: 0.5, dampingFraction: 0.4, blendDuration: 0.1).repeatForever(), value: pair)
.onAppear {
self.phase = 90
self.pair = CGSize(width: 0.1, height: 4)
}
这看起来很有希望,但不幸的是,我无法用这段代码让它产生动画效果。值参数似乎只是用作何时应用动画的触发器,但不一定使用该值来插值所使用的值。我的理解很可能有缺陷,但在任何情况下,当使用这种方法时,我都无法使其动画化。因此,如果这些值有不同的动画,这种方法非常有用——但在我的例子中,我希望两者同时动画化。使用此方法,最后一个动画将覆盖任何当前动画。最后,我改变了我的动画,使振幅和频率像这样一起被动画化,相位被一个计时器分别控制。将这个答案标记为正确,因为它帮助我走上了正确的道路。
@State private var pair: CGSize = .zero
@State private var phase: CGFloat = .zero
...
SineWaveShape(phase: phase, amplitude: amplitude, frequency: frequency)
.stroke(style: StrokeStyle(lineWidth: 3, lineCap: .round, lineJoin: .round))
.foregroundColor(.red)
.animation(Animation.linear(duration: 5).repeatForever(), value: phase)
.animation(Animation.spring(response: 0.5, dampingFraction: 0.4, blendDuration: 0.1).repeatForever(), value: pair)
.onAppear {
self.phase = 90
self.pair = CGSize(width: 0.1, height: 4)
}